java内部/外部类关于外部类私有变量访问的问题

shr*_*000 16 java decompiling class inner-classes

我有以下java类:

class Outer
{
    private Integer a;
    private Long b;

    class Inner
    {
        public void foo()
        { 
            System.out.println("a and b are " + a + " " + b);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

当我在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();
}
Run Code Online (Sandbox Code Playgroud)

我有两个问题:

1)为什么java编译器生成静态方法,在外层使用'Outer'参数来访问其私有变量?为什么不是内部类可以通过它的这个$ 0成员轻松调用的实例方法?

2)为什么内部班级的0美元成为最终?如果不是最终会发生什么?

感谢致敬.

cle*_*tus 14

非静态内部类具有对外部类的实例的隐式引用.这是作为final外部类的引用实现的.如果final技术上不是它可以在实例化后修改.

隐式传递外部类,这就是为什么内部类上的任何构造函数都具有外部类的隐式参数,这this$0是传递的方式.

编辑:至于access$000方法,关键线索是他们是包访问,他们采取Outer一个参数.因此,当Inner调用代码时,Inner.this.a它实际上是在调用Inner.access$000(this$0).因此,这些方法可以private将外部类的成员访问内部类.

  • 为什么`access $ ...()`方法需要是`static`?您提供的答案是第二个问题,以及从未提出的问题. (2认同)
  • 嗨Cletus,谢谢你的回答.我理解'access*'方法是给定的,因此内部类可以访问外部类的私有成员.但为什么这些方法是静态的?为什么他们不能成为实例方法?因为内部类有$ 0,所以代码可以很容易地调用$ 0.access $ 000,如果它是一个实例方法,而不是调用Outer.access $ 000(这个$ 0). (2认同)