Java8: lamda表达式实现原理分析

1.测试类
public class LamdaTest {

Runnable r1 = () -> {
System.out.println(this);
};

public static void main(String[] args) {
new LamdaTest().r1.run();
}

@Override
public String toString() {
return "hahaha";
}
}
2.配置启动参数-Djdk.internal.lambda.dumpProxyClasses,运行
3.反编译生成的两个类

javap -c -p LamdaTest.class (图一)
javap -c -p LamdaTest$$Lambda$1.class (图二)

【Java8: lamda表达式实现原理分析】4.分析

LamdaTest的实例对象记为:L
LamdaTest$$Lambda$1实例对象记为:R

反编译LamdaTest$$Lambda$1类

final class LamdaTest$$Lambda$1 implements Runnable {

private final LamdaTest arg$1;

private LamdaTest$$Lambda$1(LamdaTest var1) {
this.arg$1 = var1;
}
private static Runnable get$Lambda(LamdaTest var0) {
return new LamdaTest$$Lambda$1(var0);
}
@Hidden
public void run() {
this.arg$1.lambda$new$0();
}
}
LamdaTest构造函数字节码分析:

public com.ljw.LamdaTest();
Code:
0: aload_0#L加载进操作数栈
1: invokespecial #1 // Method java/lang/Object."":()V #初始化L
4: aload_0#L加载进操作数栈
5: aload_0#L加载进操作数栈 此时栈顶两个L
6: invokedynamic #2, 0 //InvokeDynamic#0:run(Lcom/ljw/LamdaTest; )Ljava/lang/Runnable;
#最终调用 LamdaTest$$Lambda$1的get$Lambda静态方法 ,其中会执行【return new LamdaTest$$Lambda$1( L ); 】这句,返回R对象,放入栈顶。
11: putfield #3// Field r1:Ljava/lang/Runnable;
#此时栈内元素为 L,R , 执行本条语句 L.r1 = R
14: return
1.在 LamdaTest 的 main 方法中调用【new LamdaTest().r1.run(); 】

2.接着执行LamdaTest$$Lambda$1.run方法中的【 this.arg$1.lambda$new$0(); 】 arg$1表示第1步中构造的LamdaTest类型的对象L。

3.接着会调用 LamdaTest 的实例方法 lambda$new$0,查看LamdaTest的反编译文件,此方法的内容就是【 () -> {System.out.println(this); } 】这个lamda表达式中的内容。
5.总结

1.在LamdaTest 类中生成一个私有方法,包装lamda表达式方法体

2.LamdaTest$$Lambda$1 中间类,起到代理的作用,最终调用 LamdaTest 中生成的私有方法。这个中间类实现函数式接口,含有一个LamdaTest的属性,含有一个返回 LamdaTest$$Lambda$1 实例的方法。


图一Java8: lamda表达式实现原理分析
文章图片

图二Java8: lamda表达式实现原理分析
文章图片




    推荐阅读