![](/img/trans.png)
[英]Why Java-8 lambda need invokeDynamic byteCode to invoke an interface method
[英]Java bytecode, java Supplier and invokedynamic argument
我有這個課,我編譯它。
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
表中的索引。 所以第一個問題, 0
實際上是指#0
。 而這又是BootstrapMethods表的索引。 它提供了invokedynamic
調用源和目標方法之間的鏈接。
如果您使用javap -c -v FileName
反編譯,您將看到整個常量池。 (我假設你做了什么?)。 在這里你應該找到對#X MethodHandle #y:#z IDDL.bootstrapDynamic
的引用#X MethodHandle #y:#z IDDL.bootstrapDynamic
。 這就是BootstrapMethods表鏈接的地方。 #0
鏈接到的句柄最終應解析為static bootstrapDynamic()
方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.