先看一下匿名内部类长什么样子:

 1 package com.jvm.demo.test2;
2
3 public class InnerClassTest {
4
5 public static void main(String[] args) {
6 new Thread(new Runnable() {
7 @Override
8 public void run() {
9 System.out.print("hello world!");
10 }
11 }).start();
12 }
13
14 }

  再看一下lambda表达式长什么样子

1 package com.jvm.demo.test2;
2
3 public class LambdaTest {
4
5 public static void main(String[] args) {
6 new Thread(() -> System.out.print("hello world!")).start();
7 }
8
9 }

  是不是长的很像,一眼能看出区别就在于参数的传递上,匿名内部类是传递的对象,而lambda表达式是传递的函数,那么我们是不是可以认为

lambda实际上就是一个语法糖,简化了部分代码?这就需要我们去看一下底层实现了。

  先把两个类都编译一遍,然后javap反编译查看class码,先来看看匿名内部类的实现:

  javap -v -p -l -s -c InnerClassTest

  

  0-11行,可以看到是分别创建了一个Thread对象和一个InnerClassTest$1对象,InnerClassTest$1对象是什么呢?可以看下面

  这下就忽然开朗了,InnerClassTest$1是一个单独的类文件,我们在目录下面也是可以看到的:

由此我们可以得出结论:匿名内部类的实现是通过创建一个类文件来实现的,那么LambdaTest又是如何实现的呢?

javap -v -p -l -s -c LambdaTest.class

  

  0-4行,调用了invokedynamic指令,invokedynamic指令是一个动态调用指令,该指令调用的代码在编译阶段不确定,在第一次运行的时候才会确定。

  4: invokedynamic #3,  0  其中的#3指向常量池中的#3:

  #0指向引导方法的0行:

  引导方法是invokedynamic都会调用的一个方法,从上面可以看出引导方法里面会调用类metafactory里面的方法,我们先去看下metafactory这个类,

这个类是一个内部类,在LambdaMetafactory里面:

  这里主要是调用了InnerClassLambdaMetafactory方法,进去看看:

  可以看出这里是根据传入的方法特征(返回值和参数)来动态构造一个类,该类的命名规则是

targetClass.getName().replace('.', '/') + "$$Lambda$" + counter.incrementAndGet();

  最终这个类会被返回出去:

 

  然后返回CallSite调用点,以便多次调用。

  之前就有人说过Lambda表达式过多影响程序性能,但是现在看来不是这样的,Lambda实际只会在第一次调用的时候动态生成类,之后调用就不会重新生成了。

  

匿名内部类和Lambda表达式是一样的吗?的更多相关文章

  1. java8 探讨与分析匿名内部类、lambda表达式、方法引用的底层实现

    问题解决思路:查看编译生成的字节码文件 目录 测试匿名内部类的实现 小结 测试lambda表达式 小结 测试方法引用 小结 三种实现方式的总结 对于lambda表达式,为什么java8要这样做? 理论 ...

  2. Java 从匿名内部类到Lambda表达式

    匿名内部类和Lambda表达式有很多类似之处,首先都是在使用的时候才对接口进行实现,只是Lambda接口中只能由一个需要被实现的方法. 所有的Lambda表达式都可以 由匿名内部类改写: interf ...

  3. Java基础学习总结(69)——匿名内部类与Lambda表达式

    前言 Java Labmda表达式的一个重要用法是简化某些匿名内部类(Anonymous Classes)的写法.实际上Lambda表达式并不仅仅是匿名内部类的语法糖,JVM内部是通过invokedy ...

  4. 17.继承 and18.接口和多态 内部类 匿名内部类,Lambda表达式

    1. 继承 1.1 继承的实现(掌握) 继承的概念 继承是面向对象三大特征之一,可以使得子类具有父类的属性和方法,还可以在子类中重新定义,以及追加属性和方法 实现继承的格式 继承通过extends实现 ...

  5. 0028 Java学习笔记-面向对象-Lambda表达式

    匿名内部类与Lambda表达式示例 下面代码来源于:0027 Java学习笔记-面向对象-(非静态.静态.局部.匿名)内部类 package testpack; public class Test1{ ...

  6. 深入探索Java 8 Lambda表达式

    2014年3月,Java 8发布,Lambda表达式作为一项重要的特性随之而来.或许现在你已经在使用Lambda表达式来书写简洁灵活的代码.比如,你可以使用Lambda表达式和新增的流相关的API,完 ...

  7. 掌握 Java 8 Lambda 表达式

    Lambda 表达式 是 Java8 中最重要的功能之一.使用 Lambda 表达式 可以替代只有一个函数的接口实现,告别匿名内部类,代码看起来更简洁易懂.Lambda 表达式 同时还提升了对 集合 ...

  8. 初探Lambda表达式/Java多核编程【2】并行与组合行为

    今天又翻了一下书的目录,第一章在这之后就结束了.也就是说,这本书所涉及到的新的知识已经全部点到了. 书的其余部分就是对这几个概念做一些基础知识的补充以及更深层次的实践. 最后两个小节的内容较少,所以合 ...

  9. Java 8 特性 —— lambda 表达式

    Lambda 表达式 Lambda表达式本质上是一个匿名方法.常见的一个例子是,在 IDEA + JDK8 的环境下按照Java传统的语法规则编写一个线程: new Thread(new Runnab ...

随机推荐

  1. 用IDEA一年了,终于敢说自己会用了

    作为Java老兵,我也是用了很多年的eclipse,为了与时俱进,于是切换到了IDEA.刚开始的时候感觉很不适应,感觉这玩意儿不如eclipse好用,影响工作效率,于是又换回eclipse. 但是很多 ...

  2. 听过N次还是不会之:浏览器输入url后到底经历了什么

    有没有这种场景:当你被问起某一项知识点时,你大脑里想起经常看到过这样的问题,可是具体是怎么样就是说不清楚. 好吧,我就是这样的,于是整理一下,实在记不住,以后找起来也方便. 当你在浏览器地址栏里输入一 ...

  3. CMOS设计手册—基础篇

    模拟CMOS 衬底噪声:由于相邻的电阻互相注入电流而产生的衬底噪声.解决方法:在两个电阻之间加入一个P+注入区(作为P衬底晶圆的衬底接触).P+注入区保护电路免受载流子的影响,由于注入区是一个环形,所 ...

  4. appium 基础二:常用api接口

    一.获取手机分辨率 size=driver.get_window_size()#获取手机屏幕大小,分辨率 print(size)#{'width': 720, 'height': 1280} 得到的是 ...

  5. Hexo + Github Pages搭建个人网站主页

    1.GitHub创建个人仓库 登录GitHub创建账号,同时拥有一个自己设定的用户名(username).点击New Repositories创建仓库.仓库名必须为username.github.io ...

  6. 阿里云openssl升级,实现nginx主动推送,nginx主动推送能够有效减少不必要的报文传输,减少用户请求次数,以达到更快访问速度

    现有版本检查 [root@node3 ~]# openssl version               #这个版本是无法支持http2.0主动推送功能.需要升级为2019版本. OpenSSL 1. ...

  7. postman -- 环境变量、全局变量使用

    背景: [登录接口]中会返回sign值,[学生金币充值接口]会则需要用到该sign值,因此把sign设置为环境或全局变量,便于其他接口调用. 1.请求登录接口,获取sign值: 2.把sign值添加至 ...

  8. 数字,字符串,逻辑比较在IF语句中的判断应用

    Shell  语言中的if条件 一.if的基本语法: if [ command ];then 符合该条件执行的语句 elif [ command ];then 符合该条件执行的语句 else 符合该条 ...

  9. linux账户的锁定和解锁、禁用账号

    l——lock锁定 S——STATUS查看 u——unlock解锁 1.通过passwd命令锁定和解锁: [root@localhost ~]# passwd -S abc ——passwd -S  ...

  10. sql注入--bool盲注,时间盲注

    盲注定义: 有时目标存在注入,但在页面上没有任何回显,此时,我们需要利用一些方法进行判断或者尝试得到数据,这个过程称之为盲注. 布尔盲注: 布尔盲注只有true跟false,也就是说它根据你的注入信息 ...