我编写了使用方法引用的简单示例:
gameid,
userid,
betid,
score
生成的字节代码是 InnerClass :
public class Main {
private static String identity(String param) {
return param;
}
public static void main(String... args) {
Function<String, String> fun = Main::identity;
System.out.println(fun.apply("Hello"));
}}
我认为这个innerClass用于lambda bootstrap方法,但我不知道jvm何时创建此类的对象以及将在此类的对象中存储哪些信息。有人能解释一下吗?
答案 0 :(得分:4)
这不是生成的内部类,而是JVMS §4.7.6中指定的InnerClasses
属性。规范要求此属性列出不是包的成员的每个类(在常量池中引用)。
基本上,javac
为它在代码中看到的所有内部类生成InnerClasses
属性。 E.g。
public class Test {
public static void main(String[] args) {
for (Map.Entry e : Collections.emptyMap().entrySet()) {
}
}
}
上述类的字节码将Map.Entry
称为Map
的内部类:
InnerClasses:
public static #31= #7 of #23; //Entry=class java/util/Map$Entry of class java/util/Map
在JDK中,lambdas使用invokedynamic
指令实现。根据规范,invokedynamic
的解析涉及使用以下类型的4个参数调用bootstrap方法:
MethodHandle
MethodHandles.Lookup
String
MethodType
Java Runtime在内部创建这些对象,但由于字节码引用MethodHandles.Lookup
类,javac
会为其生成InnerClasses
属性。