1. 定义
反射就是Reflection
,Java的反射是指程序在运行期可以拿到一个对象的所有信息。所以,反射是为了解决在运行期,对某个实例一无所知的情况下,如何调用其方法,换句话说就是反推。
我们可以得出结论:class(包括interface)的本质是数据类型(Type)。无继承关系的数据类型无法赋值。
- JVM为每个加载的class及interface创建了对应的Class实例来保存class及interface的所有信息;
- 获取一个class对应的Class实例后,就可以获取该class的所有信息;
- 通过Class实例获取class信息的方法称为反射(Reflection);
- JVM总是动态加载class,可以在运行期根据条件来控制加载class。
2. 访问字段
对于任意一个Object
实例,只要获得其Class
,就意味着可以获取一切信息。Class类提供了以下几个方法来获取字段:
- Field getField(name):根据字段名获取某个public的field(包括父类)
- Field getDeclaredField(name):根据字段名获取当前类的某个field(不包括父类)
- Field[] getFields():获取所有public的field(包括父类)
- Field[] getDeclaredFields():获取当前类的所有field(不包括父类)
获取值的方法:先获取Class实例,再获取Field实例,然后,用Field.get(Object)获取指定实例的指定字段的值。
设置字段值是通过Field.set(Object, Object)实现的,其中第一个Object参数是指定的实例,第二个Object参数是待修改的值。
一个Method对象包含一个方法的所有信息:
- getName():返回方法名称,例如:"getScore";
- getReturnType():返回方法返回值类型,也是一个Class实例,例如:String.class;
- getParameterTypes():返回方法的参数类型,是一个Class数组,例如:{String.class, int.class};
- getModifiers():返回方法的修饰符,它是一个int,不同的bit表示不同的含义。
调用方法时,用getMethod()方法。调用静态方法时,由于无需指定实例对象,所以invoke方法传入的第一个参数永远为null。为了调用非public方法,我们通过Method.setAccessible(true)允许其调用。
可以通过getSuperClass来调用获得父类class,用getInterfaces来获取继承接口。
网友评论