如何访问类子类中的私有变量?
这是我在一次面试中被问到的一个问题:我有A类私人成员,B类扩展A。我知道类的私有成员无法访问,但问题是:我需要从类B访问类A的私有成员,而不是在类B中创建具有相同值的变量。
这是我在一次面试中被问到的一个问题:我有A类私人成员,B类扩展A。我知道类的私有成员无法访问,但问题是:我需要从类B访问类A的私有成员,而不是在类B中创建具有相同值的变量。
面试官要么在测试你对访问修饰符的了解,要么在测试你改变现有类的方法,或者两者兼而有之。
我会列出它们(公共,私有,受保护,包私有),并对每个包进行解释。然后继续说,需要修改类 A 以允许从类 B 访问这些成员,方法是添加 setter 和 getter,或者通过更改成员的访问修饰符。或者B类可以使用反射。最后,谈谈每种方法的优缺点。
反射?省略导入,这应该有效:
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);
}
}
});
还有其他条件,反射方法将不起作用。有关详细信息,请参阅 SecurityManager 和 AccessibleObject 的 API 文档。感谢CPerkins指出这一点。
我希望他们只是在测试你的知识,而不是寻找这些东西的真正应用;-)尽管我认为像上面这样丑陋的黑客在某些边缘情况下可能是合法的。