汝阳网站建设哪家好,wordpress 探针,centos。wordpress,浙江信息港一、简要描述 Lambda的底层实现原理Lambda表达式编译和运行过程 二、Lambda的底层实现原理 Lambda表达式的本质 函数式接口的匿名子类的匿名对象 反编译#xff1a;cfr-0.145.jar 反编译#xff1a;LambdaMetafactory.metafactory() 跟踪调试#xff0c;转储Lambda类#x…一、简要描述 Lambda的底层实现原理Lambda表达式编译和运行过程 二、Lambda的底层实现原理 Lambda表达式的本质 函数式接口的匿名子类的匿名对象 反编译cfr-0.145.jar 反编译LambdaMetafactory.metafactory() 跟踪调试转储Lambda类 jdk.internal.lambda.dumpProxyClasses LambdaPrinciple$Lambda$1.class 结论 Lambda底层用匿名内部类实现ASM技术 Lambda表达式是个语法糖 三、Lambda表达式编译和运行过程 JVM参数jdk.internal.lambda.dumpProxyClasses 命令java -Djdk.internal.lambda.dumpProxyClasses ClassName转储得到内部类ClassName$$Lambda$1.class反编译java -jar cfr-0.145.jar LambdaPrinciple.class --decodelambdas false本质函数式接口的匿名子类的匿名对象 Lambda表达式与函数接口的抽象函数格式一一对应 1、LambdaPrinciple 代码实现
package tech.flygo.lambda.demo4;import java.util.Arrays;
import java.util.List;/*** Lambda表达式的底层实现* 语法:* (parameters) - { statements; }* 或* (parameters) - expression** p* JVM参数jdk.internal.lambda.dumpProxyClasses* 命令java -Djdk.internal.lambda.dumpProxyClasses ClassName* 转储得到内部类ClassName$$Lambda$1.class* 反编译java -jar cfr-0.145.jar LambdaPrinciple.class --decodelambdas false* p* 本质函数式接口的匿名子类的匿名对象* Lambda表达式与函数接口的抽象函数格式一一对应*/
public class LambdaPrinciple {public static void main(String[] args) {ListString stringList Arrays.asList(one, two, three);// 通过lambda表达式实现元素遍历stringList.forEach(s - {System.out.println(s);});}
}2、cfr工具包解码Lambda代码实现
CFR解析包
cfr-0.145.jarhttps://www.yuque.com/attachments/yuque/0/2023/jar/1509175/1684030971197-5456d0f4-1c6a-45d0-bf96-009ee00cd9cd.jar
2.1、复制cfr工具包到class目录下 2.2、使用Java命令解码Lambda代码实现 进入class目录class和工具包同一级目录使用java命令解码Lambda实现内容 java -jar cfr-0.145.jar LambdaPrinciple.class --decodelambdas false 2.3、解码出来的Lambda内容
/** Decompiled with CFR 0.145.*/
package tech.flygo.lambda.demo4;import java.io.PrintStream;
import java.lang.invoke.LambdaMetafactory;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;public class LambdaPrinciple {public static void main(String[] args) {ListString stringList Arrays.asList(one, two, three);stringList.forEach((ConsumerString)LambdaMetafactory.metafactory(null, null, null, (Ljava/lang/Object;)V, lambda$main$0(java.lang.String ), (Ljava/lang/String;)V)());}private static /* synthetic */ void lambda$main$0(String s) {System.out.println(s);}
}
3、分析Lambda实现逻辑
3.1、LambdaMetafactory.metafactory()方法 从下面的源码可以看出Java是严格遵循的面向对象原则这里返回的是一个对象而不是一个函数体。 3.2、调用InnerClassLambdaMetafactory 3.3、InnerClassLambdaMetafactory.buildCallSite()构造调用点 3.4、调用InnerClassLambdaMetafactory.spinInnerClass() 4、使用Java命令打开dumps调试模式 Java命令java -Djdk.internal.lambda.dumpProxyClasses ClassName 打开调试模式 4.1、进入class文件包文件的目录 特别注意比如class文件的包路径为 tech.flygo.lambda.demo4则进入目录 tech的上一级目录 执行java命令java -Djdk.internal.lambda.dumpProxyClasses tech.flygo.lambda.demo4.LambdaPrinciple 4.2、查看Lambda生成的匿名内部类 5、Java对动态语言的支持 使用javap查看class字节码javap -p -v LambdaPrinciple Java7之后增加了动态指令InvokeDynamicJava支持动态语言