Java的反射原理

视频讲解地址:https://www.bilibili.com/video/BV1Rx41197TC?from=search&seid=16603952049666504496

反射到底是什么意思?提出的目的是什么?
反射机制:Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。(就好比去医院拍CT或者其余的放射科,拍完后就能看到你整个人的具体架构,那么我们说的这个反射是通过什么去映射类呢?就是通过类的字节码文件,也就是class文件,通过class文件可以得到类的成员属性,类的构造方法,类的成员方法,相当于我们知道了类的内部构造)
当class文件被jvm加载到虚拟机内存后,就将其转换为一个的java.lang.Class对象实例,也就是说每一个字节码文件被加载后都变成了一个Class对象,通过这个对象可以获得对应类中的构造方法,成员变量,成员方法
Java的反射原理_第1张图片
所以要想实现反射,就得先获取到字节码对象(相当于CT片)
Java的反射原理_第2张图片
获取某个类的字节码对象的方式一(通过每个类从object继承到的getClass()方法)
Java的反射原理_第3张图片
获取某个类的字节码对象的方式二(通过每个类的class属性)
Java的反射原理_第4张图片
获取字节码对象的方式三(最常用的方法,Class类的静态方法forName)
Java的反射原理_第5张图片
上面已经讲了获取字节码对象的三种方法,可以看到每种方法获取的同一个类的字节码对象都是一样的,创建完字节码对象后,也就是拍好CT片后,如何通过字节码对象来反射目标类(所以要先知道这个字节码对象中包含哪些东西,也就是我们通过字节码文件可以得到目标类中的哪些东西)
Java的反射原理_第6张图片

一 使用字节码对象得到构造方法对象(Constructor),然后创建类对象

Java的反射原理_第7张图片
先定义一个实体类Person:

Package reflex;
public class Person {
    //私有属性
    private String name = "Tom";
 
    //公有属性
    public int age = 18;
 
    //构造方法1
    public Person() {   
    }
    //构造方法2
    public Person(String name,int age){
    }
 
    //私有方法
    private void say(){
        System.out.println("private say()...");
    }
 
    //公有方法
    public void work(){
        System.out.println("public work()...");
    }
}

①批量得到所有的public构造器包括父类中定义的,用getConstructors() 注意这个得不到类定义的private构造方法,我们下面也会讲到如何获取类中定义非public的构造方法
Java的反射原理_第8张图片
②批量获取所有的构造方法getDeclaredConstructors() 因为getConstructors()只能获取类中的public构造方法,获取不到其友好的,受保护的,私有的构造方法,所以引入了getDeclaredConstructors()
Java的反射原理_第9张图片
③获取某个构造器,这里用的是getConstructor(参数列表),不同于上面的带‘S’的构造器,注意里面的参数列表是根据类里定义的构造方法的参数来决定的,只不过这里传的参数是对应类型的字节码对象

1 getConstructor(参数列表) 这个方法可以获得类中声明的所有public构造器中的一个,具体是哪个根据参数列表来决定
Java的反射原理_第10张图片
2 getDeclaredConstructor(参数列表)这个方法可以获得类中声明的所有构造器中的一个,具体是哪个根据参数列表来决定
Java的反射原理_第11张图片
注意:字节码对象为我们提供了另一种快速创建对象的方法,不用先获取构造器对象,然后再创建类对象(底层调用的是类的无参构造方法,所以类中必须有无参构造方法),也就是说
Object newInstance=class.newInstance() 相当于下面的两句
Constructor constructor =class.getConstructor();
Object newInstance=constructor.getInstance();

在这里插入图片描述

二 通过字节码对象得到成员方法对象(Method)

获取方法对象和获取构造器的方法用法都一样,有四个方法getMethods getDeclaredMethods getMethod getDeclaredMethod(用法对应于上面讲的getConstructors getDeclaredConstructors getConstructor getDeclaredConstructor)
上面的构造器创建后,创建对象用getInstance,这个方法对象创建了,如何执行呢,用的是invoke(类对象,参数)
Java的反射原理_第12张图片
注意:getMethods,getMethod 可以获取到类中定义的public方法,以及父类中定义的public方法
getDeclaredMethods,getDeclaredMethod 可以获取到类中定义的全部方法,但是获取不到父类中的方法

三 通过字节码对象得到成员字段对象(Field)

获取成员字段对象和获取成员方法用法都一样,有四个方法getFields getDeclaredFields getField getDeclaredField
得到成员变量对象后 如何使用呢,用set(对象,参数)
Java的反射原理_第13张图片

你可能感兴趣的:(反射,Java开发)