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

2022-09-02 05:00:50

这是我在一次面试中被问到的一个问题:我有A类私人成员,B类扩展A。我知道类的私有成员无法访问,但问题是:我需要从类B访问类A的私有成员,而不是在类B中创建具有相同值的变量。


答案 1

面试官要么在测试你对访问修饰符的了解,要么在测试你改变现有类的方法,或者两者兼而有之。

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


答案 2

反射?省略导入,这应该有效:

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();
    }

}

如果你在调用之前做这样的事情,它将不起作用: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);    
            }
        }
    });

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

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


推荐