java反编译的静态方法参数问题6_java8 探讨与分析匿名内部类、lambda表达式、方法引用的底层实现...-程序员宅基地

技术标签: java反编译的静态方法参数问题6  

问题解决思路:查看编译生成的字节码文件

思路一:

编译 javac fileName.java

反编译 javap -v -p fileName.class ; 这一步可以看到字节码。

思路二:

运行阶段保留jvm生成的类

java -Djdk.internal.lambda.dumpProxyClasses fileName.class

本人旨在探讨匿名内部类、lambda表达式(lambda expression),方法引用(method references )的底层实现,包括实现的阶段(第一次编译期还是第二次编译)和实现的原理。

测试匿名内部类的实现

建议去对照着完整的代码来看 源码链接

基于strategy类,使用匿名内部类,main函数的代码如下,称作test1

Strategy strategy = new Strategy() {

@Override

public String approach(String msg) {

return "strategy changed : "+msg.toUpperCase() + "!";

}

};

Strategize s = new Strategize("Hello there");

s.communicate();

s.changeStrategy(strategy);

s.communicate();

第一步:现在对其使用javac编译,在Strategize.java的目录里,命令行运行javac Strategize.java,结果我们可以看到生成了5个.class文件,我们预先定义的只有4个class,而现在却多出了一个,说明编译期帮我们生成了一个class,其内容如下:

class Strategize$1 implements Strategy {

Strategize$1() {

}

public String approach(String var1) {

return var1.toUpperCase();

}

}

第二部:对生成的 Strategize.class 进行反编译,运行javap -v -c Strategize.class,在输出的结尾可以看到下面信息:

NestMembers:

com/langdon/java/onjava8/functional/Strategize$1

InnerClasses:

#9; // class com/langdon/java/onjava8/functional/Strategize$1

说明,这个Strategize$1的确是Strategize的内部类。

这个类是命名是有规范的,作为Strategize的第一个内部类,所以命名为Strategize$1。如果我们在测试的时候多写一个匿名内部类,结果会怎样?

我们修改main()方法,多写一个匿名内部类,称做test2

Strategy strategy1 = new Strategy() {

@Override

public String approach(String msg) {

return "strategy1 : "+msg.toUpperCase() + "!";

}

};

Strategy strategy2 = new Strategy() {

@Override

public String approach(String msg) {

return "strategy2 : "+msg.toUpperCase() + "!";

}

};

Strategize s = new Strategize("Hello there");

s.communicate();

s.changeStrategy(strategy1);

s.communicate();

s.changeStrategy(strategy2);

s.communicate();

继续使用javac编译一下;结果与预想的意义,多生成了2个类,分别是Strategize$1和Strategize$2,两者是实现方式是相同的,都是实现了Strategy接口的class。

小结

到此,可以说明匿名内部类的实现:第一次编译的时候通过字节码工具多生成一个class来实现的。

测试lambda表达式

第一步:修改test2的代码,把strategy1改用lambda表达式实现,称作test3

Strategy strategy1 = msg -> 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_39573512/article/details/114869630

智能推荐

台式计算机cpu允许温度,玩游戏cpu温度多少正常(台式电脑夏季CPU一般温度多少)...-程序员宅基地

文章浏览阅读1.1w次。随着炎热夏季的到来,当玩游戏正爽的时候,电脑突然死机了,自动关机了,是不是有想给主机一脚的冲动呢?这个很大的原因是因为CPU温度过高导致的。很多新手玩家可能都有一个疑虑,cpu温度多少以下正常?有些说是60,有些说是70,到底多高CPU温度不会死机呢?首先我们先看看如何查看CPU的温度。下载鲁大师并安装,运行鲁大师软件,即可进入软件界面,并点击温度管理,即可看到电脑各个硬件的温度。鲁大师一般情况下..._台式机玩游戏温度多少正常

小白自学Python日记 Day2-打印打印打印!_puthon打印任务收获-程序员宅基地

文章浏览阅读243次。Day2-打印打印打印!我终于更新了!(哭腔)一、 最简单的打印最最简单的打印语句: print(“打印内容”)注意:python是全英的,符号记得是半角下面是我写的例子:然后进入power shell ,注意:你需要使用cd来进入你保存的例子的文件夹,保存时名字应该取为xxx.py我终于知道为什么文件夹取名都建议取英文了,因为进入的时候是真的很麻烦!如果你没有进入正确的文件夹..._puthon打印任务收获

Docker安装:Errors during downloading metadata for repository ‘appstream‘:_"cenerrors during download metadata for repository-程序员宅基地

文章浏览阅读1k次。centos8问题参考CentOS 8 EOL如何切换源? - 云服务器 ECS - 阿里云_"cenerrors during download metadata for repository \"appstream"

尚硅谷_谷粒学苑-微服务+全栈在线教育实战项目之旅_基于微服务的在线教育平台尚硅谷-程序员宅基地

文章浏览阅读2.7k次,点赞3次,收藏11次。SpringBoot+Maven+MabatisPlusmaven在新建springboot项目引入RELEASE版本出错maven在新建springboot项目引入RELEASE版本出错maven详解maven就是通过pom.xml中的配置,就能够从仓库获取到想要的jar包。仓库分为:本地仓库、第三方仓库(私服)、中央仓库springframework.boot:spring-boot-starter-parent:2.2.1.RELEASE’ not found若出现jar包下载不了只有两_基于微服务的在线教育平台尚硅谷

java 实现 数据库备份_java数据备份-程序员宅基地

文章浏览阅读1k次。数据库备份的方法第一种:使用mysqldump结合exec函数进行数据库备份操作。第二种:使用php+mysql+header函数进行数据库备份和下载操作。下面 java 实现数据库备份的方法就是第一种首先我们得知道一些mysqldump的数据库备份语句备份一个数据库格式:mysqldump -h主机名 -P端口 -u用户名 -p密码 --database 数据库名 ..._java数据备份

随便推点

Discuz!代码大全-程序员宅基地

文章浏览阅读563次。1.[ u]文字:在文字的位置可以任意加入您需要的字符,显示为下划线效果。2.[ align=center]文字:在文字的位置可以任意加入您需要的字符,center位置center表示居中,left表示居左,right表示居右。5.[ color=red]文字:输入您的颜色代码,在标签的中间插入文字可以实现文字颜色改变。6.[ SIZE=数字]文字:输入您的字体大小,在标签的中间插入文..._discuzcode 大全

iOS NSTimer定时器-程序员宅基地

文章浏览阅读2.6k次。iOS中定时器有三种,分别是NSTimer、CADisplayLink、dispatch_source,下面就分别对这三种计时器进行说明。一、NSTimerNSTimer这种定时器用的比较多,但是特别需要注意释放问题,如果处理不好很容易引起循环引用问题,造成内存泄漏。1.1 NSTimer的创建NSTimer有两种创建方法。方法一:这种方法虽然创建了NSTimer,但是定时器却没有起作用。这种方式创建的NSTimer,需要加入到NSRunLoop中,有NSRunLoop的驱动才会让定时器跑起来。_ios nstimer

Linux常用命令_ls-lmore-程序员宅基地

文章浏览阅读4.8k次,点赞17次,收藏51次。Linux的命令有几百个,对程序员来说,常用的并不多,考虑各位是初学者,先学习本章节前15个命令就可以了,其它的命令以后用到的时候再学习。1、开机 物理机服务器,按下电源开关,就像windows开机一样。 在VMware中点击“开启此虚拟机”。2、登录 启动完成后,输入用户名和密码,一般情况下,不要用root用户..._ls-lmore

MySQL基础命令_mysql -u user-程序员宅基地

文章浏览阅读4.1k次。1.登录MYSQL系统命令打开DOS命令框shengfen,以管理员的身份运行命令1:mysql -u usernae -p password命令2:mysql -u username -p password -h 需要连接的mysql主机名(localhost本地主机名)或是mysql的ip地址(默认为:127.0.0.1)-P 端口号(默认:3306端口)使用其中任意一个就OK,输入命令后DOS命令框得到mysql>就说明已经进入了mysql系统2. 查看mysql当中的._mysql -u user

LVS+Keepalived使用总结_this is the redundant configuration for lvs + keep-程序员宅基地

文章浏览阅读484次。一、lvs简介和推荐阅读的资料二、lvs和keepalived的安装三、LVS VS/DR模式搭建四、LVS VS/TUN模式搭建五、LVS VS/NAT模式搭建六、keepalived多种real server健康检测实例七、lvs持久性工作原理和配置八、lvs数据监控九、lvs+keepalived故障排除一、LVS简介和推荐阅读的资料 学习LVS+Keepalived必须阅读的三个文档。1、 《Keepalived权威指南》下载见http://..._this is the redundant configuration for lvs + keepalived server itself

Android面试官,面试时总喜欢挖基础坑,整理了26道面试题牢固你基础!(3)-程序员宅基地

文章浏览阅读795次,点赞20次,收藏15次。AIDL是使用bind机制来工作。java原生参数Stringparcelablelist & map 元素 需要支持AIDL其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。下图是我进阶学习所积累的历年腾讯、头条、阿里、美团、字节跳动等公司2019-2021年的高频面试题,博主还把这些技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。