如何在其子类中访问类的私有变量?

gir*_*iri 19 java core

这是我在接受采访时被问到的一个问题:我有A级私人成员,B级扩展A.我知道一个班级的私人成员无法访问,但问题是:我需要访问A级的私人成员B类,而不是在B类中创建具有相同值的变量.

Lac*_*che 34

面试官要么测试您对访问修饰符的了解,要么测试您更改现有类的方法,或两者​​兼而有之.

我会列出它们(公共的,私有的,受保护的,包私有的)以及每个的解释.然后继续说A类需要被修改以允许通过添加setter和getter,或者通过更改成员的访问修饰符来访问B类中的那些成员.或者B类可以使用反射.最后,谈谈每种方法的优缺点.

  • 很好地解决了在面试情况下如何处理问题的工作. (5认同)

Rob*_*ier 11

反射?省略进口,这应该有效:

public class A {

    private int ii = 23;

}

public class B extends A {

    private void readPrivateSuperClassField() throws Exception {
        Class<?> clazz = getClass().getSuperclass();
        Field field = clazz.getDeclaredField("ii");
        field.setAccessible(true);
        System.out.println(field.getInt(this));
    }

    public static void main(String[] args) throws Exception {
        new B().readPrivateSuperClassField();
    }

}
Run Code Online (Sandbox Code Playgroud)

如果你在调用之前做了类似的事情,它将无法工作readPrivateSuperClassField();:

System.setSecurityManager(new SecurityManager() {
        @Override
        public void checkMemberAccess(Class<?> clazz, int which) {
            if (clazz.equals(A.class)) {
                throw new SecurityException();
            } else {
                super.checkMemberAccess(clazz, which);    
            }
        }
    });
Run Code Online (Sandbox Code Playgroud)

而且还有其他条件,反思方法不起作用.有关详细信息,请参阅SecurityManagerAccessibleObject 的API文档.感谢CPerkins指出这一点.

我希望他们只是测试你的知识,而不是寻找这些东西的真实应用;-)虽然我认为像上面这样丑陋的黑客在某些边缘情况下是合法的.


Mat*_*tis 6

架构坏了.私人会员是私人会员,因为您不希望他们在课堂和朋友之外访问.

您可以使用朋友黑客,访问者,推广会员或#define private public(嘿).但这些都是短期解决方案 - 您可能不得不在某个阶段重新审视破碎的架构.

  • 你是什​​么意思,"架构被打破了".他正在询问一个面试问题,该问题将测试他的Java知识,而不是设计一个真实的系统. (3认同)
  • 在面试问题中为#define私人公众+1 (2认同)

wj.*_*wj. 6

通过使用A的私人成员的公共访问者(getter和setter)......


fas*_*ava 5

您无法从父类访问私有成员.您已使其受保护或具有可访问它们的受保护/公共方法.

编辑:你可以使用反射.但这不是常见的,也不是打破封装的好主意.

  • 不是,你用反射. (2认同)

Gur*_*lki 1

您可以使用 A 类的 setter 和 getter。这给人的感觉就像您正在使用 A 类的对象一样。