java java内部/外部类关于外部类私有变量访问的问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2199175/
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
java inner/outer class questions about outer class private variables access
提问by shrini1000
I have the following java class:
我有以下java类:
class Outer
{
private Integer a;
private Long b;
class Inner
{
public void foo()
{
System.out.println("a and b are " + a + " " + b);
}
}
}
when I run javap on Outer and Outer$Inner, I get the following:
当我在 Outer 和 Outer$Inner 上运行 javap 时,我得到以下信息:
C:\test>javap Outer
Compiled from "Outer.java"
class Outer extends java.lang.Object{
Outer();
static java.lang.Integer access##代码##0(Outer);
static java.lang.Long access0(Outer);
}
C:\test>javap Outer$Inner
Compiled from "Outer.java"
class Outer$Inner extends java.lang.Object{
final Outer this##代码##;
Outer$Inner(Outer);
public void foo();
}
I have two questions:
我有两个问题:
1) why does java compiler generate static methods that take 'Outer' param, in the outer class, for accessing its private variables ? why not instance methods that the inner class can easily call through its this$0 member ?
1)为什么java编译器生成静态方法,在外部类中使用'Outer'参数来访问其私有变量?为什么不是内部类可以通过它的 this$0 成员轻松调用的实例方法?
2) why is this$0 in inner class made final ? what will happen if it is not final ?
2)为什么内部类中的 this$0 是 final 的?如果不是最终结果会怎样?
Thanks and regards.
谢谢并恭祝安康。
回答by cletus
Non-static inner classes have an implicit reference to an instance of the outer class. This is implemented as a finalreference to the outer class. If it wasn't finaltechnically it could be modified after instantiation.
非静态内部类具有对外部类实例的隐式引用。这是作为final对外部类的引用实现的。如果不是final技术上的,它可以在实例化后修改。
The outer class is implicitly passed in which is why any constructors on the inner class have an implicit parameter of the outer class, which is how this$0is passed in.
外部类是隐式传入的,这就是为什么内部类的任何构造函数都有一个外部类的隐式参数,这this$0就是传入的方式。
Edit:as for the access$000methods the key clue is that they're package access and they take an Outeras an argument. So when code in Innercalls, say, Inner.this.ait's actually calling Inner.access$000(this$0). So those methods are there to give access to privatemembers of the outer class to the inner class.
编辑:至于access$000方法,关键线索是它们是包访问权限,并且它们将 anOuter作为参数。所以当代码Inner调用时,比如说,Inner.this.a它实际上是在调用Inner.access$000(this$0). 所以这些方法是为了让private内部类可以访问外部类的成员。
回答by Adeel Ansari
1) They have to be static, in order to not be overridden in some sub class. I hope you understand.
1) 它们必须是static,以免在某些子类中被覆盖。我希望你明白。
<Addendum>
<Addendum>
Shrini, from your comment, it seems that there is a need to explain the things to avoid some misconceptions. First of all, know on thing that staticmethods can not be overridden. Overriding is exclusive in objects, and it is there to facilitate polymorphism. Whereas static methods belongs to the class. Found a couple of good resources to support my argument and for you to understand that static methods can not be overridden.
Shrini,从你的评论来看,似乎有必要解释一下,以避免一些误解。首先,要知道static方法不能被覆盖。覆盖在对象中是排他的,它是为了促进多态性。而静态方法属于类。找到了一些很好的资源来支持我的论点,并让您了解不能覆盖静态方法。
Now for your second retort, you are right in saying that they have package level access and can't be overridden in subclasses outside the package. But I don't know why are you neglecting the case where subclass/es exist in the same package. Its a valid case, IMO. In fact, it would be absurd to name a method like access$000()or something like that, in a real work. But don't underestimate the chance of accidental overriding. There can be a case where the subclass of Outer, say SubOuter, has an inner class of itself too. I didn't try to javapthat case myself, just guessing.
现在对于您的第二个反驳,您说它们具有包级别访问权限并且不能在包外的子类中被覆盖是正确的。但是我不知道你为什么忽略子类/es存在于同一个包中的情况。这是一个有效的案例,IMO。事实上,access$000()在实际工作中命名类似或类似的方法是荒谬的。但不要低估意外覆盖的可能性。可能存在这样的情况Outer,例如SubOuter,的子类也具有自身的内部类。我自己没有尝试过javap这种情况,只是猜测。
</Addendum>
</Addendum>
2) Even if you think it will not get modified, technically there is a possibility as cletus pointed out already, use of finalcan provide easy optimizations by the compiler.
2) 即使您认为它不会被修改,从技术上讲,正如 cletus 已经指出的那样,使用final可以为编译器提供简单的优化。

