如此处所述:
“可访问性是可以在编译时确定的静态属性;它仅取决于类型和声明修饰符。”
在这种情况下,函数在运行时java.lang.reflect.Field.setAccessible(boolean)
真正做了什么?
setAccessible
不会改变成员的可访问性级别。它只允许通过反射访问某个成员。这并没有明确破坏可访问性规则,因为您的代码并没有真正访问该成员:它调用了一个反射方法,该方法在内部执行了一些魔法,代表您访问该成员。
考虑到这一点,还有一个关键点需要注意:Java 还有一个非常强大且不可穿透的安全系统,可以拒绝对外部代码使用反射。每当需要时,这种机制可用于真正防止访问私有成员。
您的报价不适用于反射 API。JLS #1.4明确指出,您可以通过 JLS 未明确授权的反射操作来实现:
因此,本规范没有详细描述反射。许多语言结构在反射 API 中都有类似物,但这里一般不讨论。因此,例如,当我们列出可以创建对象的方式时,我们通常不包括反射 API 可以完成此操作的方式。读者应该知道这些额外的机制,即使它们在本文中没有提到。
我允许您使用反射更改对象的可访问性,正如您所期望的那样。从类的javadocAccessibleObject
:
在反射对象中设置可访问标志允许具有足够特权的复杂应用程序(例如 Java 对象序列化或其他持久性机制)以通常被禁止的方式操作对象。