先看一段代码
public class Lambda {
public static void main(String[] args) {
System.setProperty("jdk.internal.lambda.dumpProxyClasses", ".");
Function<Integer, String> fun1 = String::valueOf;
Function<String, Integer> fun2 = String::length;
System.out.println(fun1.apply(1));
System.out.println(fun2.apply("hello"));
}
}
那么,javac为我们做了什么呢?等价与那些代码呢?
对于第一种为
public static void main(String[] args) throws Throwable {
MethodHandles.Lookup caller = MethodHandles.lookup();
String invokedName = "apply";
MethodType invokedType = MethodType.methodType(Function.class);
MethodHandle implMethod = caller.findStatic(String.class, "valueOf",
MethodType.methodType(String.class,int.class));
MethodType instantiatedMethodType = MethodType.methodType(String.class,int.class);
CallSite site = LambdaMetafactory.metafactory(caller,
invokedName,
invokedType,
instantiatedMethodType.generic(),
implMethod,
instantiatedMethodType);
MethodHandle factory = site.getTarget();
Function<Integer,String> fun1 = (Function<Integer,String>) factory.invoke();
System.out.println(fun1.apply(1));
}
第二种为
MethodHandles.Lookup caller = MethodHandles.lookup();
String invokedName = "apply";
MethodType invokedType = MethodType.methodType(Function.class);
MethodHandle implMethod = caller.findVirtual(String.class, "length",
MethodType.methodType(int.class));
MethodType instantiatedMethodType = MethodType.methodType(int.class,String.class);
CallSite site = LambdaMetafactory.metafactory(caller,
invokedName,
invokedType,
instantiatedMethodType.generic(),
implMethod,
instantiatedMethodType);
MethodHandle factory = site.getTarget();
Function<String,Integer> fun2 = (Function<String,Integer>) factory.invoke();
System.out.println(fun2.apply("hello"));
生成的具体类为
第一个
final class Lambda$$Lambda$1
implements Function {
private Lambda$$Lambda$1() {
}
@LambdaForm.Hidden
public Object apply(Object object) {
return String.valueOf((Integer)object);
}
}
第二个
final class Lambda$$Lambda$2
implements Function {
private Lambda$$Lambda$2() {
}
@LambdaForm.Hidden
public Object apply(Object object) {
return ((String)object).length();
}
}