gpt4 book ai didi

Java 字节码、java Supplier 和 invokedynamic 参数

转载 作者:塔克拉玛干 更新时间:2023-11-01 23:06:40 24 4
gpt4 key购买 nike

我有这个类,我编译它。

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 接口(interface)的匿名实例。传递给 invokedynamic 的是两个参数,一个是#3。第二个参数是 0。因此,我的第一个问题是:0 在这里代表什么?

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

最佳答案

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

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

关于Java 字节码、java Supplier 和 invokedynamic 参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38632794/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com