考虑下面这个例子:
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;
}
似乎没有什么道理,你可以访问类的私人领域与反思。 为什么是这样的功能是否可用? 是不是很“危险”,让这样的访问?
私人旨在防止意外误用,而不是作为一种安全机制。 如果您选择跳过它,那么你可以在你自己的风险,假设这样做,你知道你在做什么。
无论getDeclaredField()
和setAccessible()
实际上是由安全管理检查,将抛出一个异常时,你的代码是不允许这样做。 更多的,往往不是你不会注意到它,因为Java代码通常没有安全管理器上运行。
一个重要的例外是小程序,它总是与安全管理器运行。
是的,它不是很好,但它确实允许的框架,如Java序列工作。
在反射对象中设置accessible标志允许具有足够的权限复杂的应用程序,如Java对象序列化或其他持久性机制,操作通常会被禁止的方式对象。
我beleive,该功能可以通过禁用SecurityManager
http://javabeans.asia/2008/10/12/how_to_set_securitymanager_and_java_security_policy_programmatically.html
反思是危险的。 期。
是什么在限制非常危险系统的效用非常轻微增加安全起见点?
另外,自动序列需要“吸大脑”的任何类的能力; 忽略访问修饰符在这种情况下是必要的。
反思是获得类内一个完整的API。 私有成员和所有。
在情况下,你不信任你的代码正在运行程序(applet等),你可以防止代码使用反射的。 见这个堆栈溢出问题的详细信息。
从所述的说明中java.lang.reflect
包:
类此包,伴随着java.lang.Class
(基于适应应用,如调试器,口译员,督察对象,类浏览器和服务,如对象序列化和需要访问到任何一个目标对象的公共成员的JavaBeans其运行时类)或通过一个给定的类声明的成员。
反射提供了一种用于通过装置,该装置通常是不可用的类和对象之间的交互规则访问关于类的信息的机制。 一种这样的被允许访问外部类和对象的私有字段。
是的,在一般的反思的确是危险的,因为它可以公开的类和对象的内部。
然而,它也是一个非常强大的工具,可以用来检查类和对象的内部,无法通过其他标准来进行访问。
来源: http://java.sun.com/docs/books/tutorial/reflect/
反射通常是由需要检查或修改在Java虚拟机上运行的应用程序运行时行为能力的程序中使用。
这是一个工具,可以让一个打破一些规则,一个把它扔了他的脚在或正确地使用它。