java-11之前的内部类访问字段

Eug*_*ene 4 java jvm javac

有这样的课程:

public class Sample1 {

    public class Inner {
        private int f;
    }

    void go() {
        Inner in = new Inner();
        int value = in.f;
    }

}
Run Code Online (Sandbox Code Playgroud)

该方法的字节码go(在 java-11 之前)调用已知的合成方法:

static int access$000(nestmates.Sample1$Inner);
    descriptor: (Lnestmates/Sample1$Inner;)I
    flags: ACC_STATIC, ACC_SYNTHETIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: getfield      #1                  // Field f:I
         4: ireturn
Run Code Online (Sandbox Code Playgroud)

从:

0: new  #2  // class nestmates/Sample1$Inner
3: dup
4: aload_0
5: invokespecial #3 // Method nestmates/Sample1$Inner."<init>":(Lnestmates/Sample1;)V
8: astore_1
9: aload_1
10: invokestatic #4 // Method nestmates/Sample1$Inner.access$000:(Lnestmates/Sample1$Inner;)I
Run Code Online (Sandbox Code Playgroud)

我知道这件事已经有一段时间了,但我从来没有问过自己为什么会这样?为什么 javac 必须首先执行此操作,为什么不直接getField通过静态方法进行此间接操作。谢谢。

apa*_*gin 7

因为 JVM不允许访问不同类的私有成员,无论它是否是内部类。JDK 11 添加了Nestmate的概念来克服这个限制。