一、反射原理分析
1.1 类和Java文件的关系
class大括号{}以内
1.成员变量 Field
2.成员方法 Constructor
3.成员方法 Methd
当前java文件包含class的所有内容
1.2 class字节码文件和Java文件关系
Java文件通过javac.exe编译之后,会得到一个.class字节码文件。
字节码文件是根据当前Java文件中包含的class来对应生成.class文件
.class是二进制文件,提供给JVM运行操作使用的二进制文件。
.class字节码包含对应类所有内容。
1.3 .class字节码文件执行和内存关系
计算机中所有的程序,都是在内存中运行执行的!!!
.class字节码文件通过java.exe执行之后,会在内存的【方法区】占用一定的空间。内存【方法区】就是当前程序运行的可执行内容。
程序的加载过程 ==> .class字节码文件加载到内存的【方法区】
【重点】
在内存【方法区】.class字节码文件占用的内存空间,包含的所有的.class字节码文件内容。
二、反射的方法
作用:不用经过实例化的过程,就能获取类,类对象,类方法,等等
使用场景:如各种底层的封装需要用到反射机制,增加封装的普适性!!
2.1 获取class类对象
static Class forName(String className);
通过类名调用,是一个静态方法,传入参数是一个完整的包名.类名
Class 类名.class
通过制定的类名调取,获取类内所对应的属性,一般用于方法参数数据类型约束。
Class 类对象.getClass();
通过类对象获取当前类对象Class。
2.2 获取Constructor构造方法类对象
Constructor[] getconstructors();
获取当前class对象对应class中的所有非私有化构造方法对象数组.
Constructor[] getDeclaredConstructors();
获取当前Class对象对应class中所有构造方法对象数组,包括私有化构造方法(暴力反射)
Constructor getConstructor(Class...initParameterType);
根据构造方法参数数据类型,通过Class类对象调用,获取对应Constructor非私有构造方法类对象。
initParameterTypes: 要求数据类型是Class类型的不定长参数,用于约束当前获取的构造方法对应哪一个参数列表。
Constructor getDeclaredConstructor(Class...initParameterType);
根据构造方法参数数据类型,通过Class类对象调用,获取对应Constructor构造方法类对象。可以获取私有化构造方法
initParameterTypes: 要求数据类型是Class类型的不定长参数,用于约束当前获取的构造方法对应哪一个参数列表。(暴力反射)
Object newInstance(Object...ParameterValues);
通过Constructor对象调用,创建对应的类对象,需要的参数是当前Constructor对应参数数据类型的实际参数.
2.3 获取Method成员方法类对象
Method[] getMethods();
获取当前类内的所有非私有化方法,包括从父类继承可以在子类使用的成员方法。
Method[] getDeclaredMethods();
获取当前类内的所有方法,包括私有化成员方法,但是不包括从父类继承的方法。
Method getMethod(String methodName, Class... parameterTypes);
根据方法名字和对应的参数类型,个数,顺序获取指定的非私有化成员方法。
methodName: 方法名
Class... parameterTypes: 方法所需参数类型列表
Method getDeclaredMethod(String methodName, Class... parameterTypes);
根据指定方法名和对应参数数据类型,个数,顺序获取类内的成员方法,包括私有化成员方法。
2.3.1 调用Method类对象【重点】
Object invoke(Object obj, Object... values);
通过Method类对象调用,执行当前Method类对象对应的方法。
obj: 执行当前方法的类对象
values: 不定长参数,是当前方法所需的实际参数
2.4 获取Field成员变量类对象
Field[] getFields();
获取类内的所有非私有化成员变量Field类对象数组
Field[] getDeclaredFields();
获取类内的所有成员变量Field类对象数组,并且包括私有化成员变量。
Field getField(String fieldName);
获取类内指定名字的成员变量类对象,要求非私有化
Field getDeclaredField(String fieldName);
获取类内的指定名字成员变量类对象,可以是私有化成员变量
【给予暴力反射操作权限】
void setAccessible(boolean flag);
public static void setAccessible(AccessibleObject[] array, boolean flag);
AccessibleObject[] array
可访问的对象数组,这里可以传入Field,Method和Constructor数组
boolean flag 给予操作权限