Lambda 表达式详解~深入JVM实现原理
读过上一篇之后,相信对Lambda表达式的语法以及基本原理有了一定了解。对于编写代码,有这些知识已经够用。本文将进一步区分Lambda表达式和匿名内部类在JVM层面的区别,如果对这一部分不感兴趣,可以跳过。
经过第一篇的的介绍,我们看到Lambda表达式似乎只是为了简化匿名内部类书写,这看起来仅仅通过语法糖在编译阶段把所有的Lambda表达式替换成匿名内部类就可以了。但实时并非如此。在JVM层面,Lambda表达式和匿名内部类有着明显的差别。
匿名内部类实现
匿名内部类仍然是一个类,只是不需要程序员显示指定类名,编译器会自动为该类取名。因此如果有如下形式的代码,编译之后将会产生两个class文件:
public class MainAnonymousClass {public static void main(String[] args) {new Thread(new Runnable(){@Overridepublic void run(){System.out.println("Anonymous Class Thread run()");}}).start();;}
}
编译之后文件分布如下,两个class文件分别是主类和匿名内部类产生的:
进一步分析主类MainAnonymousClass.class的字节码,可发现其创建了匿名内部类的对象:
// javap -c MainAnonymousClass.class
public class MainAnonymousClass {...public static void main(java.lang.String[]);Code:0: new #2 // class java/lang/Thread3: dup4: new #3 // class MainAnonymousClass$1 /*创建内部类对象*/7: dup8: invokespecial #4 // Method MainAnonymousClass$1."<init>":()V11: invokespecial #5 // Method java/lang/Thread."<init>":(Ljava/lang/Runnable;)V14: invokevirtual #6 // Method java/lang/Thread.start:()V17: return
}
Lambda表达式实现
Lambda表达式通过invokedynamic指令实现,书写Lambda表达式不会产生新的类。如果有如下代码,编译之后只有一个class文件:
public class MainLambda {public static void main(String[] args) {new Thread(() -> System.out.println("Lambda Thread run()")).start();;}
}
编译之后的结果:
通过javap反编译命名,我们更能看出Lambda表达式内部表示的不同:
// javap -c -p MainLambda.class
public class MainLambda {...public static void main(java.lang.String[]);Code:0: new #2 // class java/lang/Thread3: dup4: invokedynamic #3, 0 // InvokeDynamic #0:run:()Ljava/lang/Runnable; /*使用invokedynamic指令调用*/9: invokespecial #4 // Method java/lang/Thread."<init>":(Ljava/lang/Runnable;)V12: invokevirtual #5 // Method java/lang/Thread.start:()V15: returnprivate static void lambda$main$0(); /*Lambda表达式被封装成主类的私有方法*/Code:0: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream;3: ldc #7 // String Lambda Thread run()5: invokevirtual #8 // Method java/io/PrintStream.println:(Ljava/lang/String;)V8: return
}
反编译之后我们发现Lambda表达式被封装成了主类的一个私有方法,并通过invokedynamic指令进行调用。
推论,this引用的意义
既然Lambda表达式不是内部类的简写,那么Lambda内部的this
引用也就跟内部类对象没什么关系了。在Lambda表达式中this
的意义跟在表达式外部完全一样。因此下列代码将输出两遍Hello Hoolee
,而不是两个引用地址。
public class Hello {Runnable r1 = () -> { System.out.println(this); };Runnable r2 = () -> { System.out.println(toString()); };public static void main(String[] args) {new Hello().r1.run();new Hello().r2.run();}public String toString() { return "Hello Hoolee"; }
}
Lambda 表达式详解~深入JVM实现原理相关推荐
- java拉姆达表达式事例,Java Lambda表达式详解和实例
简介 Lambda表达式是Java SE 8中一个重要的新特性.lambda表达式允许你通过表达式来代替功能接口. lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体( ...
- java lambda表达式详解_Java8新特性Lambda表达式详解
课程目标: 通过本课程的学习,详细掌握Java8新特性之Lambda表达式: 适用人群:有Java基础的开发人员: 课程概述:从Java 8出现以来lambda是最重要的特性之一,它可以让我们用简洁流 ...
- Java8 Lambda表达式详解手册及实例
先贩卖一下焦虑,Java8发于2014年3月18日,距离现在已经快6年了,如果你对Java8的新特性还没有应用,甚至还一无所知,那你真得关注公众号"程序新视界",好好系列的学习一下 ...
- Lambda 表达式详解~Stream Pipelines
前面我们已经学会如何使用Stream API,用起来真的很爽,但简洁的方法下面似乎隐藏着无尽的秘密,如此强大的API是如何实现的呢?比如Pipeline是怎么执行的,每次方法调用都会导致一次迭代吗?自 ...
- Lambda 表达式详解~Lambda与集合
我们先从最熟悉的*Java集合框架(Java Collections Framework, JCF)*开始说起. 为引入Lambda表达式,Java8新增了java.util.funcion包,里面包 ...
- java lambda表达式详解_Java8新特性:Lambda表达式详解
在 Java 版本的历次更新迭代中,Java8 是一个特殊的存在,与以往的版本升级不同.我们对 Java8 似乎抱有更大的期待,因为它是 Java5 之后最重要的一次升级,提供了十多个新特性,其中 L ...
- 【C++】Lambda 表达式详解
语法糖:Lambda 表达式 一.Lambda表达式简介 二.Lambda表达式语法解析 1. Lambda exp 基本语法结构 2. 捕获变量的几种方式 3. mutable关键字 三.Lambd ...
- java Lambda表达式详解
文章目录 一.背景 1.1语法 1.2函数式接口 二.Lambda的基本使用 2.1引子 2.2常见的使用方式 2.3语法小结 三.变量捕获 3.1 匿名内部类 3.2 匿名内部类的变量捕获 3.3L ...
- JAVA之Lambda表达式详解
文章目录 一.基本概念 1.背景 2.Lambda表达式的语法 3.函数式接口 二.Lambda表达式的基本使用 1.无返回值函数式接口 2.有返回值函数接口 3.语法精简 三.变量捕获 1.匿名内部 ...
最新文章
- 阿里一面:如何保障消息100%投递成功、消息幂等性?
- PowerShell导出共存环境下的Exchange数据库列表
- 双击SDK Manager.exe和AVD Manager.exe时,弹出提示:failed to execute tools\android.bat解决办法
- 静态成员变量的初始化,vector类型变量初始化
- 可以对同一个html元素定义不同的样式,CSS的多种选择器的使用.ppt
- python通过ip池爬_python爬虫18 | 就算你被封了也能继续爬,使用IP代理池伪装你的IP地址,让IP飘一会...
- 获取python安装路径
- 微信小程序 基础操作(边做边学2)
- python读取csmar_Python:爬取上市公司公告-Wind-CSMAR
- 傅里叶变换及拉普拉斯变换直观理解总结
- linux卫星添加,卫星电视卡在linux下的应用
- c语言编程入门教程+网易,人话讲编程·C语言入门:第一讲,Hello World
- vb里的lbound和ubound的用法
- 计算机系统硬件有哪些重要的部件呢?
- 【踩坑】RTX30系列显卡的CUDA配置
- java并发-ReentrantReadWriteLock读写锁
- 域名批量查询 网站域名批量查询
- 2022软考高级架构设计师-经历分享
- 英酷词典 使用方法 必知必会
- 【笔记】2022.5.9 网页数据收集
热门文章
- Netty堆外内存泄露排查盛宴
- java架构师进阶之独孤九剑:数据结构以及书籍推荐
- Python中实现模糊匹配的魔法库:FuzzyWuzzy
- 维多利亚的秘密 2005-2018年视频合集
- windows下安装Sublime+Miktex+Sumatrapdf配置LATEX环境
- Android官方开发文档Training系列课程中文版:Activity测试之测试环境配置
- 记录对String.format(Formatter().format())方法的总结
- BUAA_OO_第二单元作业总结
- 编程开发之--java多线程学习总结(3)类锁
- MySQL索引的索引长度问题