Multiple this$1 fields when mixing subclassing and inner classes

David Holmes david.holmes at
Mon Sep 9 23:17:22 UTC 2019

On 10/09/2019 9:09 am, Stefan Reich wrote:
>     But you're not talking about bytecode here you're talking about inside
>     the VM. If there is an invokespecial on this$1 of type A then the
>     constant pool lookup of its type will be A and we will resolve the call
>     based on A's methods. If it were of type B then the resolution process
>     would be different. There's nowhere to "insert a cast" here.
> Can invokespecials on this$0/this$1 happen? I'm struggling to imagine a 
> case for this.
> invokespecial invokes private instance methods, superclass methods or 
> constructors. Superclass methods don't apply, neither do constructors. 
> And calls to private methods happen through bridges (just verified this 
> for myself again :):
>        13: aload_0
>        14: getfield      #1                  // Field this$0:Lbla;
>        17: invokestatic  #4                  // Method 
> bla.access$000:(Lbla;)V
> So what remains?

This changed in JDK 11 with the addition of nestmates. Now inner classes 
have direct private access, no bridges needed, and we use invokespecial 
or invokevirtual as appropriate. For private methods invokevirtual is 
mainly used now, but of course we don't do virtual dispatch - there are 
special rules for private method resolution and selection.

class A {
   void m() {}
   class InnerA {
     void callM() { m(); }

  void callM();
     descriptor: ()V
     flags: (0x0000)
       stack=1, locals=1, args_size=1
          0: aload_0
          1: getfield      #1                  // Field this$0:LA;
          4: invokevirtual #13                 // Method A.m:()V
          7: return
         line 4: 0

>     BTW what introspection tool did you use to show this?
> My own tools ("JavaX")... here's the example program: 

Thanks for the pointer.


> Many greetings :)

More information about the hotspot-dev mailing list