Java 如何在其子类中访问类的私有变量?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2258891/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to access the private variables of a class in its subclass?
提问by giri
This is a question I was asked in an interview: I have class A with private members and Class B extends A. I know private members of a class cannot be accessed, but the question is: I need to access private members of class A from class B, rather than create variables with the same value in class B.
这是我在采访中被问到的一个问题:我有一个带有私有成员的类 A 和类 B 扩展了 A。我知道不能访问类的私有成员,但问题是:我需要从B 类,而不是在 B 类中创建具有相同值的变量。
回答by GuruKulki
You can use the setters and getters of class A. Which gives same feeling as if You are using a class A's object.
您可以使用 A 类的 setter 和 getter。这给人的感觉就像您在使用 A 类的对象一样。
回答by Matt Curtis
The architecture is broken. Private members are private because you do not want them accessed outside the class and friends.
架构坏了。私有成员是私有的,因为您不希望在课堂和朋友之外访问它们。
You can use friend hacks, accessors, promote the member, or #define private public
(heh). But these are all short term solutions - you will probably have to revisit the broken architecture at some stage.
您可以使用朋友黑客、访问器、提升成员或#define private public
(呵呵)。但这些都是短期解决方案——您可能需要在某个阶段重新审视损坏的架构。
回答by fastcodejava
You cannot access private members from the parent class. You have make it protected or have protected/public method that has access to them.
您不能从父类访问私有成员。您已将其设置为受保护或具有可访问它们的受保护/公共方法。
EDIT: It is true you can use reflection. But that is not usual and not good idea to break encapsulation.
编辑:确实可以使用反射。但这并不常见,也不是打破封装的好主意。
回答by Tomas Vana
Have you thought about making them protected? Just to be sure you are aware of this option, if you are then pardon me for bringing up this trivia ;)
你有没有想过让他们受到保护?只是为了确保您知道此选项,如果您当时请原谅我提出这个琐事;)
回答by oltman
If I'm understanding the question correctly, you could change private
to protected
. Protected variables are accessible to subclasses but behave like private variables otherwise.
如果我正确理解了这个问题,您可以更改private
为protected
. 子类可以访问受保护的变量,但其他方面的行为类似于私有变量。
回答by Lachlan Roche
The interviewer was either testing your knowledge of access modifiers, or your approach to changing existing classes, or both.
面试官要么测试你对访问修饰符的了解,要么测试你改变现有类的方法,或者两者兼而有之。
I would have listed them (public, private, protected, package private) with an explanation of each. Then gone on to say that class A would need to be modified to allow access to those members from class B, either by adding setters and getters, or by changing the access modifiers of the members. Or class B could use reflection. Finally, talk about the pros and cons of each approach.
我会列出它们(公共的、私有的、受保护的、私有的包)并解释每个。然后继续说需要修改类 A 以允许从类 B 访问这些成员,方法是添加 setter 和 getter,或者通过更改成员的访问修饰符。或者 B 类可以使用反射。最后,谈谈每种方法的优缺点。
回答by Robert Petermeier
Reflection? Omitting imports, this should work:
反射?省略进口,这应该工作:
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();
}
}
It'll not work if you do something like that before the of invocation 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);
}
}
});
And there are other conditions under which the Reflection approach won't work. See the API docs for SecurityManagerand AccessibleObjectfor more info. Thanks to CPerkins for pointing that out.
还有其他条件下反射方法不起作用。有关更多信息,请参阅SecurityManager和AccessibleObject的 API 文档。感谢 CPerkins 指出这一点。
I hope they were just testing your knowledge, not looking for a real application of this stuff ;-) Although I think an ugly hack like this above can be legit in certain edge cases.
我希望他们只是测试你的知识,而不是寻找这些东西的真正应用;-) 尽管我认为像上面这样的丑陋黑客在某些极端情况下可能是合法的。
回答by wj.
By using public accessors (getters & setters) of A's privates members ...
通过使用 A 的私有成员的公共访问器(getter 和 setter)......
回答by Syed M Shaaf
Private will be hidden until you have been given the right access to it. For instance Getters or setters by the programmer who wrote the Parent. If they are not visible by that either then accept the fact that they are just private and not accessible to you. Why exactly you want to do that??
私人将被隐藏,直到您获得正确的访问权限。例如编写 Parent 的程序员的 Getter 或 setter。如果它们不可见,那么接受它们只是私人的并且您无法访问的事实。你为什么要这样做?
回答by Marc Gravell
I don't know about Java, but in some languages nestedtypes can do this:
我不了解 Java,但在某些语言中,嵌套类型可以做到这一点:
class A {
private string someField;
class B : A {
void Foo() {
someField = "abc";
}
}
}
Otherwise, use an accessor method or a protected
field (although they are often abused).
否则,使用访问器方法或protected
字段(尽管它们经常被滥用)。