Java 字节码,java 供应商和 invokedynamic 参数
Java bytecode, java Supplier and invokedynamic argument
我有这个class,我编译它。
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 在这里代表什么?
#0
(你可以在 invokedynamic 旁边的注释中看到)实际上是 BootstrapMethods
table 中的一个索引。所以第一个问题,0
实际上是指#0
。而这又是 BootstrapMethods table 的索引。它在 invokedynamic
调用源和目标方法之间提供了一个 link。
如果您使用 javap -c -v FileName
进行反编译,您将看到整个常量池。 (我假设你已经做了?)。在这里您应该找到对 #X MethodHandle #y:#z IDDL.bootstrapDynamic
的引用。这就是 BootstrapMethods table link 的目的。 #0
link 的句柄最终应该解析为 static bootstrapDynamic()
方法。
我有这个class,我编译它。
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 在这里代表什么?
#0
(你可以在 invokedynamic 旁边的注释中看到)实际上是 BootstrapMethods
table 中的一个索引。所以第一个问题,0
实际上是指#0
。而这又是 BootstrapMethods table 的索引。它在 invokedynamic
调用源和目标方法之间提供了一个 link。
如果您使用 javap -c -v FileName
进行反编译,您将看到整个常量池。 (我假设你已经做了?)。在这里您应该找到对 #X MethodHandle #y:#z IDDL.bootstrapDynamic
的引用。这就是 BootstrapMethods table link 的目的。 #0
link 的句柄最终应该解析为 static bootstrapDynamic()
方法。