简体   繁体   English

Java字节码,java供应商和invokedynamic参数

[英]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函数的开头:

  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. 在这里我们可以看到invokedynamic调用,如果我理解正确的话,它会创建一个Supplier接口的匿名实例。 Passed to invokedynamic are two arguments, one is #3. 传递给invokedynamic有两个参数,一个是#3。 The second argument is 0. So, my first question is: what does 0 stand here for? 第二个参数是0.所以,我的第一个问题是:0代表什么?

In constant pool #3 stands for #3 = InvokeDynamic #0:#27 // #0:get:()Ljava/util/function/Supplier; 在常量池#3中代表#3 = InvokeDynamic #0:#27 // #0:get:()Ljava/util/function/Supplier; . There is reference to #27 in constant pool, but no reference to #0. 在常量池中引用#27,但没有引用#0。 My second question is: what does #0 stand for here? 我的第二个问题是:#0代表什么?

The #0 (which you can see in the comment next to the invokedynamic) is actually an index in the BootstrapMethods table. #0 (您可以在invokedynamic旁边的注释中看到)实际上是BootstrapMethods表中的索引。 So the first question, the 0 actually refers to #0 . 所以第一个问题, 0实际上是指#0 And that in turn is the index of the BootstrapMethods table. 而这又是BootstrapMethods表的索引。 Which provides a link between the invokedynamic call origin and the targeted method. 它提供了invokedynamic调用源和目标方法之间的链接。

If you would decompile with javap -c -v FileName you will see the whole constant pool. 如果您使用javap -c -v FileName反编译,您将看到整个常量池。 (Which I am assuming you have done?). (我假设你做了什么?)。 Here you should find a reference to #X MethodHandle #y:#z IDDL.bootstrapDynamic . 在这里你应该找到对#X MethodHandle #y:#z IDDL.bootstrapDynamic的引用#X MethodHandle #y:#z IDDL.bootstrapDynamic That is the point where the BootstrapMethods table links to. 这就是BootstrapMethods表链接的地方。 The handle that the #0 links to, should eventually resolve to a static bootstrapDynamic() method. #0链接到的句柄最终应解析为static bootstrapDynamic()方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM