1、代码
定义一个函数式接口
@FunctionalInterface
public interface Func<T,R> extends Serializable {
R apply(T t);
}
定义一个用户类
public class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
main()方法
public static void main(String[] args) throws Throwable {
//
Func<Person, String> getNameFunction = Person::getName;
Class<?> clazz = getNameFunction.getClass();
Method writeReplace1 = ReflectUtil.getMethod(clazz, "writeReplace");
writeReplace1.setAccessible(true);
// 调用方法
System.out.println(writeReplace1.invoke(getNameFunction));
// 使用 MethodHandles 操作方法
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodHandle learnProMh = lookup.unreflect(writeReplace1);
SerializedLambda serializedLamb = (SerializedLambda) learnProMh.invoke(getNameFunction);
System.out.println(serializedLamb);
}
vm运行参数
-Djdk.internal.lambda.dumpProxyClasses=<path>
运行程序
得到程序结果如下
SerializedLambda[capturingClass=class com.example.demo.Demo1Application, functionalInterfaceMethod=com/example/demo/Demo1Application$Func.apply:(Ljava/lang/Object;)Ljava/lang/Object;, implementation=invokeVirtual com/example/demo/Demo1Application$Person.getName:()Ljava/lang/String;, instantiatedMethodType=(Lcom/example/demo/Demo1Application$Person;)Ljava/lang/String;, numCaptured=0]
lambda 字节码如下:
final class Demo1Application$$Lambda$2 implements Demo1Application.Func {
private Demo1Application$$Lambda$2() {
}
@Hidden
public Object apply(Object var1) {
return ((Demo1Application.Person)var1).getName();
}
private final Object writeReplace() {
return new SerializedLambda(Demo1Application.class, "com/example/demo/Demo1Application$Func", "apply", "(Ljava/lang/Object;)Ljava/lang/Object;", 5, "com/example/demo/Demo1Application$Person", "getName", "()Ljava/lang/Integer;", "(Lcom/example/demo/Demo1Application$Person;)Ljava/lang/Integer;", new Object[0]);
}
}
2、原理
1、 当函数式接口继承 Serializable 接口,lambda 字节码会生成 writeReplace 方法返回SerializedLambda对象,该对象包含了原方法的信息