为什么允许通过reflection访问Java私有字段?
考虑这个例子:
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; }
你被允许通过反思访问私人领域的课程似乎是不合逻辑的。 为什么这样的function可用? 允许这种访问不是“危险的”吗?
私人意图是为了防止意外滥用,而不是作为一种安全机制。 如果你select绕过它,那么你可以自己承担风险,并假设你知道你在做什么。
getDeclaredField()
和setAccessible()
实际上都是由安全pipe理器检查的,当你的代码不被允许的时候会抛出一个exception。 更多的时候你不会注意到它,因为Java代码通常运行时没有安全pipe理器。
一个重要的例外是Applets,它总是与安全经理一起运行。
是的,它不是很好,但它确实允许Java序列化等框架工作。
在reflection对象中设置可访问标志允许具有足够权限的复杂应用程序(如Java Object Serialization或其他持久机制)以通常禁止的方式操作对象。
我相信通过SecurityManager
可以禁用这个function
反思是危险的。 期。
为了使安全性稍微提高,限制真正危险的系统的效用有什么意义?
另外,自动化序列化需要能够从任何课堂“吸取大脑”; 忽略访问修饰符在这种情况下是必需的。
reflection是一个完成的内部类的API。 私人会员和所有。
如果您不信任正在运行的代码(小程序等),则可以防止代码使用reflection。 有关详细信息,请参阅此堆栈溢出问题 。
从java.lang.reflect
包的描述 :
这个包中的类以及
java.lang.Class
包含debugging器,解释器,对象检查器,类浏览器和对象序列化和JavaBeans等服务,它们需要访问目标对象的公共成员(基于它运行时类)或由给定类声明的成员。
reflection提供了一种通过类和对象之间的常规交互通常不可用的方式访问类的信息的机制。 其中之一是允许从外部类和对象访问私人领域。
是的,反思总的来说确实可能是危险的,因为它可以暴露阶级和对象的内部。
但是,它也是一个非常强大的工具,可以用来检查类和对象的内部,而这些工具是其他标准手段无法访问的。
来自: http : //java.sun.com/docs/books/tutorial/reflect/
reflection通常被需要能够检查或修改Java虚拟机中运行的应用程序的运行时行为的程序所使用。
这是一个可以让人打破一些规则的工具,可以把它放在脚上或正确使用它。