5、获取Class中的字段
5.1 getField(String name) 只获取共有的字段
- 返回一个 Field对象,它反映此表示的类或接口的指定公共成员字段 类对象。
/**
* 获取字节码文件的字段
*/
@Test
public void getFieldDemo() throws Exception {
Class clazz = Class.forName("com.hw.bean.Person");
Field name = clazz.getField("name");
System.out.println(name);
}
运行:
报错,原因是字段是私有的。
要反映的字段由以下算法确定。 让C成为由该对象表示的类或接口:
- 如果C声明一个具有指定名称的公共字段,那就是要反映的字段。
- 如果在上述步骤1中没有找到字段,则将该算法递归地应用于C的每个直接超级接口。直接超级接口按照它们被声明的顺序被搜索。
- 如果在上面的步骤1和2中没有找到字段,并且C具有超类S,则该算法在S上递归地调用。如果C没有超类,则抛出NoSuchFieldException 。
5.2 getDeclaredField(String name) 只获取本类 但包含私有
@Test
public void getFieldDemo() throws Exception {
Class clazz = Class.forName("com.hw.bean.Person");
Field field = // clazz.getField("name");
clazz.getDeclaredField("name");
Object instance = clazz.newInstance();
Object age = field.get(instance);
}
运行:
还是报错,不能访问私有的
5.3 java.lang.reflect.AccessibleObject
- AccessibleObject类是Field,Method和Constructor对象的基类。 它提供了将反射对象标记为在使用它时抑制默认Java语言访问控制检查的功能。
- 当使用Fields,Methods或Constructors来设置或获取字段,调用方法,或创建和初始化新的类实例时,执行访问检查(对于public,默认(包)访问,受保护和私有成员)。
5.3.1 setAccessible(boolean flag) 暴力访问
- 将此对象的 accessible标志设置为指示的布尔值。
@Test
public void getFieldDemo() throws Exception {
Class clazz = Class.forName("com.hw.bean.Person");
Field field = // clazz.getField("name");
clazz.getDeclaredField("name");
// 对私有字段的访问取消权限检查。暴力访问
field.setAccessible(true);
Object instance = clazz.newInstance();
// 对字段赋值
field.set(instance,"张四");
Object name = field.get(instance);
System.out.println(name);
}
运行:
本章节源码: ReflectDemo3