Search code examples
javajava-8bytecodeinvokedynamic

Java bytecode, java Supplier and invokedynamic argument


I have this class, and I compile it.

package org.test;

import java.util.function.Supplier;

public class Test {
    static String get() { return "!!"; }

    public static void main(String[] args) {
        Supplier<String> sup = Test::get;
        System.out.println(sup.get());
    }
}

Then, trying to look into it's bytecode, I get following beginning of public static void main function:

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=2, args_size=1
         0: invokedynamic #3,  0              // InvokeDynamic #0:get:()Ljava/util/function/Supplier;
         5: astore_1
         6: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;

Here we can see the invokedynamic call, which, if I understand correctly, creates anonymous instance of Supplier interface. Passed to invokedynamic are two arguments, one is #3. The second argument is 0. So, my first question is: what does 0 stand here for?

In constant pool #3 stands for #3 = InvokeDynamic #0:#27 // #0:get:()Ljava/util/function/Supplier;. There is reference to #27 in constant pool, but no reference to #0. My second question is: what does #0 stand for here?


Solution

  • The #0 (which you can see in the comment next to the invokedynamic) is actually an index in the BootstrapMethods table. So the first question, the 0 actually refers to #0. And that in turn is the index of the BootstrapMethods table. Which provides a link between the invokedynamic call origin and the targeted method.

    If you would decompile with javap -c -v FileNameyou will see the whole constant pool. (Which I am assuming you have done?). Here you should find a reference to #X MethodHandle #y:#z IDDL.bootstrapDynamic. That is the point where the BootstrapMethods table links to. The handle that the #0 links to, should eventually resolve to a static bootstrapDynamic() method.