为什么允许它通过反射访问Java私有字段?
考虑这个例子:为什么允许它通过反射访问Java私有字段?,java,reflection,private-members,Java,Reflection,Private Members,考虑这个例子: import java.lang.reflect.Field; public class Test { public static void main(String[] args) { C c = new C(); try { Field f = C.class.getDeclaredField("a"); f.setAccessible(true); Intege
import java.lang.reflect.Field;
public class Test {
public static void main(String[] args) {
C c = new C();
try {
Field f = C.class.getDeclaredField("a");
f.setAccessible(true);
Integer i = (Integer)f.get(c);
System.out.println(i);
} catch (Exception e) {}
}
}
class C {
private Integer a =6;
}
允许您使用反射访问类的私有字段似乎不合逻辑。为什么有这样的功能?允许这种访问不是“危险”吗?反射是危险的。句号 为了稍微提高安全性,限制一个真正危险系统的效用有什么意义 此外,自动序列化要求能够从任何类中“吸取大脑”;在这种情况下,必须忽略访问修饰符。来自: 反射通常用于需要能够检查或修改Java虚拟机中运行的应用程序的运行时行为的程序 这是一种可以让人打破某些规则的工具,人们可以把它扔到自己的脚上或正确使用它。来自软件包: 此包中的类,以及
java.lang.Class
调试器等应用程序,
解释器、对象检查器、类
浏览器,以及对象等服务
需要
访问
目标对象(基于其运行时)
类)或
给定的类
反射提供了一种机制,用于通过类和对象之间的常规交互通常不可用的方式访问有关类的信息。其中之一是允许从外部类和对象访问私有字段
是的,反射通常确实是危险的,因为它会暴露类和对象的内部
然而,它也是一个非常强大的工具,可以用来检查类和对象的内部结构,而其他标准方法无法访问这些内部结构。是的,这并不好,但它确实允许Java序列化等框架工作 在反射对象中设置可访问标志允许具有足够权限的复杂应用程序(如Java对象序列化或其他持久化机制)以通常禁止的方式操作对象 我相信可以通过
SecurityManager
安全管理器实际上会检查
getDeclaredField()
和setAccessible()
这两个字段,如果不允许您的代码执行此操作,则会引发异常。您通常不会注意到这一点,因为Java代码通常在没有安全管理器的情况下运行
一个重要的例外是applet,它总是与安全管理器一起运行。反射是进入类内部的完整API。私人成员和所有人
如果您不信任正在运行的代码(applet等),则可以阻止代码使用反射。有关详细信息,请参阅。专用是为了防止意外误用,而不是作为安全机制。如果您选择绕过它,那么您可以自行承担风险,并且假设您知道自己在做什么。+1完全正确的private是对其他程序员的一个提示,提示他们不应该关心保持类运行的成员。它使您能够将代码排序为一些契约,并让编译器检查契约,而不是直接编写或读取这些成员。但是如果你不得不违反合同,你可以这样做,因为编程语言不应该妨碍程序员,即使他想自杀。所以总而言之,封装或者我应该说——数据隐藏都是关于加密的,与安全无关,即使您以第三方的身份提供API,您也会说“Java代码通常在没有安全管理器的情况下运行”。没有默认的安全管理器?哇。。。“重要”和“小程序”在同一句话中。那是过去的日子。我将把它作为时代如何变化的见证:-)