java内部/外部类关于外部类私有变量访问的问题
我有以下java类:
class Outer { private Integer a; private Long b; class Inner { public void foo() { System.out.println("a and b are " + a + " " + b); } } }
当我在Outer和Outer $ Inner上运行javap时,我得到以下内容:
C:\test>javap Outer Compiled from "Outer.java" class Outer extends java.lang.Object{ Outer(); static java.lang.Integer access$000(Outer); static java.lang.Long access$100(Outer); } C:\test>javap Outer$Inner Compiled from "Outer.java" class Outer$Inner extends java.lang.Object{ final Outer this$0; Outer$Inner(Outer); public void foo(); }
我有两个问题:
1)为什么java编译器生成静态方法,在外层类中使用’Outer’参数来访问其私有变量? 为什么不是内部类可以通过它的这个$ 0成员轻松调用的实例方法?
2)为什么内部阶级的这个0美元成为最终的? 如果不是最终会发生什么?
感谢致敬。
非静态内部类具有对外部类的实例的隐式引用。 这是作为外部类的final
引用实现的。 如果它在技术上不是final
它可以在实例化后修改。
外部类是隐式传递的,这就是为什么内部类上的任何构造函数都有外部类的隐式参数,这就是传递this$0
原因。
编辑:对于access$000
方法,关键线索是他们是包访问,他们将Outer
作为参数。 因此,当Inner
调用的代码,例如, Inner.this.a
它实际上调用Inner.access$000(this$0)
。 因此,那些方法可以访问内部类的外部类的private
成员。
1)它们必须是static
,以免在某些子类中被覆盖。 我希望你明白。
Shrini,从你的评论来看,似乎有必要解释一些事情以避免一些误解。 首先,要知道static
方法无法覆盖的事情。 覆盖在对象中是唯一的,它可以促进多态性。 而静态方法属于该类。 找到了一些很好的资源来支持我的论点,并让你理解静态方法不能被覆盖。
- 你能用Java覆盖静态方法吗?
- 为什么静态方法不能抽象
现在,对于您的第二次反驳,您说他们具有包级别访问权限并且无法在包外部的子类中重写。 但我不知道为什么你忽略了同一个包中存在子类/ es的情况。 它是一个有效的案例,IMO。 实际上,在实际工作中命名一个类似access$000()
或类似的方法是荒谬的。 但是不要低估意外覆盖的可能性。 可能存在一种情况,即Outer
的子类,比如SubOuter
,也有自己的内部类。 我自己并没有尝试过这种情况,只是猜测。
2)即使你认为它不会被修改,技术上也有可能已经指出了cletus,使用final
可以提供编译器的简单优化。