为什么允许通过反射访问Java私有字段?

Sav*_*sis 43 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);
            Integer i = (Integer)f.get(c);
            System.out.println(i);
        } catch (Exception e) {}
    }
}

class C {
    private Integer a =6;
}
Run Code Online (Sandbox Code Playgroud)

允许您通过反射访问类的私有字段似乎不合逻辑.为什么有这样的功能?允许这种访问不是"危险的"吗?

jco*_*der 58

Private旨在防止意外滥用,而不是作为安全机制.如果您选择绕过它,那么您可以自担风险并假设您知道自己在做什么.

  • +1完全正确的私有是一个暗示其他程序员,他们不应该关心成员保持课程运行.它使您能够将代码分类为某些合同,并让编译器检查您不直接编写或读取这些成员的合同.但是如果你必须违反合同,你就可以做到这一点,因为编程语言不应该妨碍程序员,即使他想让自己陷入困境. (4认同)

Joa*_*uer 22

安全管理器实际上检查了这两个getDeclaredField()并且setAccessible()在您的代码不允许执行此操作时将抛出异常.通常情况下,您不会注意到它,因为Java代码通常在没有安全管理器的情况下运行.

一个重要的例外是Applet,它总是与安全管理器一起运行.

  • 哇......同一句话中的"重要"和"小程序".那些日子.我会把它留下来作为时代变化的证明:-) (2认同)

pjp*_*pjp 10

是的,这并不好,但它确实允许Java序列化等框架工作.

在反射对象中设置可访问标志允许具有足够权限的复杂应用程序(例如Java对象序列化或其他持久性机制)以通常被禁止的方式操作对象.

我相信可以通过以下方式禁用该功能 SecurityManager

http://javabeans.asia/2008/10/12/how_to_set_securitymanager_and_java_security_policy_programmatically.html


Kev*_*ose 8

反思是危险的.期.

为了安全性的提高,限制真正危险系统的效用有什么意义?

此外,自动序列化需要能够从任何类别"吸取大脑"; 在这种情况下,忽略访问修饰符是必要的.