- 反射
框架的设计灵魂
反射:将类的各个组成部分封装为其他对象,就是反射机制
* 成员变量: Field[] fields
* 构造方法:Constructor[] cons
* 成员方法:Method[] methods
Java代码在计算中经历的阶段:
1. Source源代码阶段
2. class类对象阶段
3. Runtime运行阶段
反射的优点:
* 可以在程序的运行中,操作这些对象
* 可以解耦,提高程序的可扩展性
5.1 获取class
1. Source源代码阶段:`Class.forName("全类名")`,将字节码文件加载进内存,返回class对象。多用于配置文件,将类名定义在配置文件中,读取文件,加载类。
2. class类对象阶段:`类名.class`。多用于参数的传递。
3. Runtime运行阶段:`对象.getClass()`,此方法在object中定义。多用于对象字节码获取的方式
public static void main(String[] args) throws ClassNotFoundException {
Class cls1 = Class.forName("day05.Demo.Reflcet.domain.Person");
Class cls2 = Person.class;
Person p = new Person();
Class cls3 = p.getClass();
System.out.println(cls1); // class day05.Demo.Reflcet.domain.Person
System.out.println(cls1==cls2); // true
System.out.println(cls1==cls3); // true
System.out.println(cls2==cls3); // true
}
同一个字节码文件(*.class)在一次程序的运行中,只会被加载一次,无论通过哪一种方式获取的Class对象获取的均是同一个
5.2 获取与操作成员变量
5.2.1 获取
1. `Field[] getFields()`:获取所有public修饰的成员变量
2. `Field[] getField(String name)`:获取指定名称的public修饰的成员变量
3. `Field[] getDeclaredFields()`: 获取所有的成员变量,不考虑修饰符
4. `Field[] getDeclaredField(String name)`
5.2.2 操作
1. `get(object obj)` : 获取值
2. `set(object obj, object value)` :设置值
在访问非public成员变量时,需要忽略访问权限修饰符的安全检测(暴力反射):
Field b = personClass.getDeclaredField("b");
b.setAccessible(true) // 暴力反射,Constructor与Method同样的操作
5.3 获取操作构造方法
5.3.1 获取
1. `Constructor<T> getConstructor(类<?>... parameterTypes)`
eg:`personClass.getConstructor(String.class,int.class)`
5.3.2 操作
用来创建对象:
T newInstance(Object... init)
,传递真实的参数,返回对象实例
推荐使用class对象的 newInstance 方法使用空参构造方法创建对象
personClass.newInstance()
5.4 获取操作成员方法
5.4.1 获取
1. `Method[] getMethods()`(包括继承自Objcet类及父类,public修饰)
2. `Method getMethod(String name,类<?>... parameterTypes)`
3. `Method[] getDeclaredMethods()`(只获取属于本类的所有方法,无论修饰符)
4. `Method[] getDeclaredMethod(String name,类<?>... parameterTypes)`
5.4.2 操作
执行方法:
Object invoke(Object obj,Object... args)
,传递创建的对象与参数列表
获取方法名:
String getName()
5.5 获取类名
Class 类的方法:String getName();