【问题标题】:Java bytecode, java Supplier and invokedynamic argumentJava字节码、Java供应商和invokedynamic参数
【发布时间】:2016-07-28 09:48:13
【问题描述】:

我有这个类,我编译它。

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());
    }
}

然后,试图查看它的字节码,我得到以下 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;

在这里我们可以看到invokedynamic 调用,如果我理解正确的话,它会创建Supplier 接口的匿名实例。 传递给invokedynamic 的是两个参数,一个是#3。 第二个参数是 0。所以,我的第一个问题是:这里的 0 代表什么?

在常量池中#3 代表#3 = InvokeDynamic #0:#27 // #0:get:()Ljava/util/function/Supplier;。常量池中有对#27 的引用,但没有对#0 的引用。 我的第二个问题是:#0 在这里代表什么?

【问题讨论】:

    标签: java java-8 bytecode invokedynamic


    【解决方案1】:

    #0(您可以在invokedynamic 旁边的注释中看到)实际上是BootstrapMethods 表中的一个索引。所以第一个问题,0 实际上是指#0。而这又是 BootstrapMethods 表的索引。它提供了invokedynamic 调用源和目标方法之间的链接。

    如果您使用javap -c -v FileName进行反编译,您将看到整个常量池。 (我假设你已经完成了?)。在这里您应该找到对#X MethodHandle #y:#z IDDL.bootstrapDynamic 的引用。这就是 BootstrapMethods 表链接到的点。 #0 链接到的句柄最终应该解析为 static bootstrapDynamic() 方法。

    【讨论】:

    • 您的意思是 0: #32 invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; 来自 BootstrapMethods: ?但这是一个指令,而不是价值
    • @DmitryV。你期望什么价值?
    • 如果#0 引用#32 invokestatic ..yadayada..,我无法解释InvokeDynamic #0:#27
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-23
    • 2014-05-19
    • 1970-01-01
    • 2011-08-18
    • 1970-01-01
    相关资源
    最近更新 更多