JAVA--反射

一、什么是类对象

类的对象:基于某个类new出来的对象,也称为实例对象。

类对象:类加载的产物,封装了一个类的所有信息(类名、父类、接口、属性、方法、构造方法)。

注:每个类加载到内存都会生成一个唯一的类对象。

二、获取类对象的方法

2.1 通过类的对象,获取类对象

Person p = new Pserson();
Class c = p.getclass();

2.2 通过类名获取类对象

Class c = 类名.class;

2.3 通过静态方法获取类对象(任何类型都有.class)

Class c = Class.forName("包名.类名");

2.4  ReflectUtil

Hutool工具包中工具类

2.5 示例

 未使用工具类进行反射:

    /**
     * 获取实体类字段的description
     *
     * @param clazz
     * @return
     */
    private static Map<String, String> getFieldSwaggerValue(Class clazz) {
        Field[] fields = clazz.getDeclaredFields();
        Map<String, String> map = new HashMap<>();
        for (Field f : fields) {
            boolean annotationPresent2 = f.isAnnotationPresent(ApiModelProperty.class);
            if (annotationPresent2) {
                ApiModelProperty name = f.getAnnotation(ApiModelProperty.class);
                String nameStr = name.value();
                map.put(f.getName(), nameStr);
            }
        }
        return map;
    }

ReflectUtil 工具类进行反射: 

Map<String, Field> xssoAccount = ReflectUtil.getFieldMap(XssoAccount.class);

三、反射机制

1、反射机制有什么用?

通过java语言中的反射机制可以操作字节码文件,可以读和修改字节码文件,通过反射机制可以操作代码片段(class文件)。

2、反射机制的相关类在哪个包下?

java.lang.reflect.*

3、反射机制相关的类有哪些?

java.lang.Class 代表字节码文件

java.lang.reflect.Method 代表字节码中的方法字节码

java.lang.reflect.Constructor 代表字节码中的构造方法的字节码

java.lang.reflect.Field 代表字节码中的属性字节码

4、通过反射实例化对象

Class c = Class.forName("包.User");    //c代表User类型
Object obj = c.newInstance();   //newInstance()这个方法会调用User这个类的无参构造方法,完成对象的创建

优点:使程序更加灵活,代码不需要改动,可以修改配置文件,配置文件修改之后,可以创建出不同的实例对象。

    public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {

//       通过IO流读取。properties文件(具有局限性,只能在idea中)
        FileReader reader = new FileReader("./src/classinfo.properties");
//        创建属性类对象
        Properties pro=new Properties();
//        加载
        pro.load(reader);
//        关闭流
        reader.close();
//        通过key获取value
        String className = pro.getProperty("className");
//        通过反射机制实例化对象
        Class c = Class.forName(className);
        Object obj = c.newInstance();
        System.out.println(obj);
    }

5、 以流的形式直接返回

    public static void main(String[] args) throws IOException {
//        获取一个文件的绝对路径
        InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("classinfo.properties");
        Properties pro = new Properties();
        pro.load(is);
        is.close();
//        通过key获取value
        String className = pro.getProperty("className");
        System.out.println(className);
    }

6、资源绑定器

    public static void main(String[] args) {
//        java.util包下提供了一个资源绑定器,便于获取配置文件中的内容
//        属性配置文件xxx.properties必须放在类路径下(src)
//        资源绑定器,只绑定xxx.properties文件,并且这个文件必须在类路径下,文件扩展名也必须是properties
//        并且在写路径的时候,路径后面的路径扩展名不能写
        ResourceBundle bundle = ResourceBundle.getBundle("classinfo");
        String className = bundle.getString("className");
        System.out.println(className);

    }

7、类加载器

7.1 定义

        专门赋值加载类的命令/工具,ClassLoader

7.2 JDK中自带3个类加载器

          1、启动类加载器:rt.jar
          2、扩展类加载器: ext\*.jar
          3、应用类加载器: classpath

7.3  假设有这样一段代码:

        String s = "abc";

        代码在开始执行之前,会将所需要类全部加载到JVM中,通过类加载器加载,看到以上代码类加载器会找到String.class文件,找到就加载,那么是怎么加载的呢?

        1、首先通过"启动类加载器"加载
        注意: 启动类加载器专门加载这个包下的东西:

                C:\Program Files\Java\jdk1.8.0_101\jre\lib\rt.jar这是JDK中核心的类库

        2、如果通过"启动类加载器"加载不的到时候,
就会通过扩展类加载器去加载:C:\Program Files\Java\jdk1.8.0_101\jre\lib\ext*.jar
        3、如果"扩展类加载器"没有加载到,那么会通过"应用类加载器"加载。
        注意:应用加载器专门加载:classpath中的类。

8、双亲委派

        优先从启动类加载器中加载,这个称为"父",“父"无法加载到,再从扩展类中加载, 这个称为"母”。这就是双亲委派。
        如果都加载不到才会考虑从应用类加载器中加载。直到加载到为止。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值