Search code examples
javajvmjavac

Inner class access field before java-11


Having a class like this:

public class Sample1 {

    public class Inner {
        private int f;
    }

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

}

The byte-code for the go method (before java-11) calls that known synthetic method:

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

from:

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

I've known about this for quite some time, but I've never questioned myself why this is like this? Why javac has to do this in the first place, and why not directly getField and this indirection via the static method. Thank you.


Solution

  • Because JVMS doesn't allow access to private members of a different class, whether it is an inner class or not. JDK 11 added the concept of nestmates to overcome this limitation.