Java反射:框架设计的灵魂
设计框架用的,学会能对框架有更好的理解
- 反射:将类的各个组成部分封装为其他对象,这就是反射机制
- 好处:
- 可以在程序运行过程中,操作这些对象
- 可以解耦,提高程序的可拓展性
- 好处:
类对象
什么是类对象
类对象
,就是用于描述这种类,都有什么属性,什么方法的
作用:
从class文件里提取出一个类的成员变量
、构造方法
、成员方法
(主要)
并将其封装成数组Field[] fields
、Constructor[] cons
、Method[] methods
获取类对象方式
获取类对象有3种方式
- Class.forName(“全类名”) //将字节码文件加载进内存,返回Class对象
- 全类名,就是包名.类名
- 多用于配置文件,将类名定义在配置文件中。读取文件,加载类
- 类名.class //通过类名的属性class获取
- 多用于参数的传递
- 已经实例对象.getClass() //getClass()在Object类中定义着(换句话说:所有类都这个方法)
- 多用于对象的获取字节码的方式
在一个JVM中,一种类,只会有一个类对象存在。所以以上三种方式取出来的类对象,都是一样的
。
方法示例:
package reflection;
import charactor.Hero;
public class TestReflection {
public static void main(String[] args) {
String className = "charactor.Hero";
try {
Class pClass1=Class.forName(className);
Class pClass2=Hero.class;
Class pClass3=new Hero().getClass();
System.out.println(pClass1==pClass2);
System.out.println(pClass1==pClass3);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
获取类对象的时候,会导致类属性被初始化
无论什么途径获取类对象,都会导致静态属性被初始化,而且只会执行一次。(除了直接使用 Class c = Hero.class 这种方式,这种方式不会导致静态属性被初始化)
类对象功能(即获取类的各个部分)
获取成员变量们
Field[] getFields() :获取所有public修饰的成员变量,包括
从父类继承来
的变量Field getField(String name) :获取指定名称的public修饰的成员变量,包括
从父类继承来
的Field[] getDeclaredFields() :获取所有的成员变量,不考虑修饰符,但是
不能获取继承来
的字段Field getDeclaredField(String name) :获取指定名称的成员变量,不考虑修饰符,但是
不能获取继承来
的字段
获取构造方法们
Constructor<?>[] getconstructors()
Constructor> getconstructor(类>… parameterTypes)
Constructor
getDeclaredconstructor() Constructor<?>[] getDeclaredconstructors()
获取成员方法们
Method[] getMethods()
Method getMethod(String name,类)
Method[] getDeclaredMethods()
Method getDeclaredMethod(String name,类)
获取类名
- String getName()
获取类的各个部分之后,进行的操作
Field:成员变量
操作
设置值
- void set(Object obj,Object value)
获取值
- get(Object obj)
忽略访问权限修饰符的安全检查
- setAccessible(true) :暴力反射(用于
访问和修改
private修饰的成员变量的值,对于其他类的部分也能使用)
- setAccessible(true) :暴力反射(用于
Constructor:构造方法
创建对象:
用获取到的构造器调用newInstance()
如果使用空参数构造方法创建对象,操作可以简化:Class对象的newInstance()方法(Object提供的)
Method:方法对象
执行方法
- Object invoke(Object obj,Object args)
获取方法名称:
- String getName:获取方法名