什么是反射?
- 反射:能够获取并分析类信息的能力叫做反射。
- 类信息包括:属性(Field),方法(Method),构造器(Constructor)。
获取类信息的三种方式:
方式 | 备注 |
---|
通过==Class.forName(“完整的类名带包名”)==获取 | 通过路径获取,多用于配置文件,将类名定义在配置文件中,读取文件加载类 |
通过==类对象.getClass()==获取 | 多用于使用对象来获取对象信息 |
通过类.class获取 | 多用于类作为参数传递的情况 |
public static void main(String[] args) throws ClassNotFoundException {
Class cla = Class.forName("com.test.Person");
Field[] fields = cla.getFields();
Class cla1 = Person.class;
Person p = new Person();
Class cla2 = p.getClass();
}
- **类信息.get…**方法可以获取到public修饰的方法和成员变量,**类信息.getDeclare…**方法可以获取到任意方法和成员变量。
- setAccessible(true):非公共成员变量如果想有效使用需要设置忽略安全访问修饰符的安全检查(简称暴力反射)。
获取构造方法
获取指定的构造方法
- 获取类信息:
Class.forName()
,返回类型为Class
。 - 获取构造方法对象:
类信息.getConstructor()
,返回类型为Constructor
类型。 - 获取类对象:
类信息.newInstance()
(反射之后通过newInstance
方法拿到类对象),返回类型为Object
类型。
Class cla = Class.forName("com.test.Person");
Constructor constructor = cla.getConstructor();
Constructor constructor = cla.getConstructor(String.class, int.class);
Object object = constructor.newInstance();
获取所有的构造方法
Constructor[] constructors = cla.getConstructors();
for (Constructor cons : constructors) {
System.out.println(cons);
}
获取成员变量
获取指定成员变量
- 获取类信息:
Class.forName()
,返回类型为Class
。 - 获取成员变量对象:
类信息.getField()
,返回类型为Field
类型。 - 设置值
set(Object obj, Object value)
,获取值get(Object obj)
。
Class cla = Class.forName("com.test.Person");
Field field = cla.getField("name");
Field fieldAll = cla.getDeclareField("age");
Person p = new Person();
field.set(p, "张三");
field.get(p);
fieldAll.setAccessible(true);
fieldAll.set(p, 18);
获取所有成员变量
Field[] fields = cla.getFields();
for (Field f : fields) {
System.out.println(f);
}
Field[] fields = cla.getDeclareFields();
for (Field f : fields) {
System.out.println(f);
}
方法使用
获取指定方法对象
- 获取类信息:
Class.forName()
,返回类型为Class
。 - 获取指定方法对象:
类信息.getMethod()
或getDeclareMethod()
,区别同上,根据方法名以及参数类型入参对应类对象可以指定获取,返回类型为Method
。 - 调用方法:
invoke(Object obj, Object... args)
。第一个入参为调用方法的对象,后面的可变参数为方法调用需要传入的参数。
获取所有方法对象
getMethods()
和getDeclareMethods()
,用法同上。