2.6 访问非公有成员
Java 的 访问权限检查 可以被禁用,禁用之后就可以访问 protected package private 的字段、方法了,若不能禁用该检查,序列化是无法实现的。
java.lang.reflect.AccessibleObject 是 Field 和 Method 的 共同父类,AccessibleObject 中的 setAccessible 方法可以禁止、开启运行时访问权限的检查。
对于 Field 类型的实例 f:
f.setAccessible(true);
setAccessible 开启的是 使用元对象 时候的权限检查,上面禁止了所有使用 元对象 f 时的访问权限检查,即可以使用 Field 访问 private 等原本无权限访问的字段。
将该功能加入 serializeObject 中,现在可以访问 所有访问权限 的字段了:
if (! Modifier.isPublic( field.getModifiers() )) {
field.setAccessible(true);
}
Object value = field.get(obj);
setAccessible 方法的作用
该方法定义在 Field 和 Method 的父类 AccessibleObject 中,对这两个类意义不同:
Field而言,将可以对 任意限定符 修饰的字段使用get/set方法。Method而言,将可以用invoke调用方法。
AccessibleObject 类的方法
AccessibleObject 中的方法签名如下:
| 方法签名 | 说明 |
|---|---|
| void setAccessible(boolean flag) | 设置调用对象的 访问标志 |
| boolean isAccessible() | 访问标志是否为 true |
| static void setAccessible(AccessibleObject[] array, boolean flag) | 为数组中的元素批量设置访问权限 |
异常
设置访问权限的功能可能被 安全管理器 禁止,若被禁止,则 setAccessible 方法将抛出 SecurityException 异常。
安全管理器默认允许设置调用对象的 类加载器 加载的类的成员。