这几天复习了 lambda ,发现有个细节,十分难以理解,那就是 lambda 里的 this指针。

Lambda 里的this指针指向其所属的内部类, 是怎么实现的呢?

写了一个例子,作为测试:

import java.util.function.Supplier;

public class LambdaTest {

public static void main(String[] args) {

new LambdaTest().test();

}

public void test() {

String para = "abc";

String para2 = "abc";

System.out.println(this);

Supplier supplier = () -> {

return para + para2;

};

System.out.println(supplier.get());

}

}

对应的jvm 机器码是:

private static java.lang.String lambda$test$0(java.lang.String, java.lang.String);

descriptor: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;

flags: ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC

Code:

stack=2, locals=2, args_size=2

0: new #12 // class java/lang/StringBuilder

3: dup

4: invokespecial #13 // Method java/lang/StringBuilder."":()V

7: aload_0

8: invokevirtual #14 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;

11: aload_1

12: invokevirtual #14 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;

15: invokevirtual #15 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;

18: areturn

LineNumberTable:

line 16: 0

通过方法签名可以知道,如果一个类没有带 this,被编译成了一个静态内部类方法。

带 this:

import java.util.function.Supplier;

public class LambdaTest {

public static void main(String[] args) {

new LambdaTest().test();

}

public void test() {

String para = "abc";

String para2 = "abc";

System.out.println(this);

Supplier supplier = () -> {

System.out.println(this);

return para + para2;

};

System.out.println(supplier.get());

}

}

对应的 jvm 机器码:

private java.lang.String lambda$test$0(java.lang.String, java.lang.String);

descriptor: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;

flags: ACC_PRIVATE, ACC_SYNTHETIC

Code:

stack=2, locals=3, args_size=3

0: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream;

3: aload_0

4: invokevirtual #7 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V

7: new #12 // class java/lang/StringBuilder

10: dup

11: invokespecial #13 // Method java/lang/StringBuilder."":()V

14: aload_1

15: invokevirtual #14 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;

18: aload_2

19: invokevirtual #14 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;

22: invokevirtual #15 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;

25: areturn

LineNumberTable:

line 15: 0

line 16: 7

lambda 被编译成了一种内部类!这就能说通了。

结论:

lambda一般情况下会被编译成静态匿名方法,引用的外部变量以参数的方式传递。

如果 lambda 里使用了this 指标,则被编译为匿名内部方法,以让 this 指针指向lambda 外部类。

java8 lambda this_java8里lambda里的 this 为什么会指向 lamdba 所在的外部类相关推荐

  1. lambda 两个list获取交集_《Java8 实战》笔记 - Lambda 表达式

    Lambda 表达式介绍 ​ 可以把Lambda表达式理解为简洁地表示可传递的匿名函数的一种方式:它没有名称,但它 有参数列表.函数主体.返回类型,可能还有一个可以抛出的异常列表.这个定义够大的,让我 ...

  2. Java8新特性之- Lambda表达式和函数式接口

    Lambda表达式和函数式接口 1. 背景 Java是一门面向对象编程语言.面向对象编程语言和函数式编程语言中的基本元素(Basic Values)都可以动态封装程序行为:面向对象编程语言使用带有方法 ...

  3. java8新特性: lambda表达式:直接获得某个list/array/对象里面的字段集合

    java8新特性: lambda表达式:直接获得某个list/array/对象里面的字段集合 比如,我有一张表: entity Category.java service CategoryServic ...

  4. java 8 stream_深度分析:java8的新特性lambda和stream流,看完你学会了吗?

    1. lambda表达式 1.1 什么是lambda 以java为例,可以对一个java变量赋一个值,比如int a = 1,而对于一个方法,一块代码也是赋予给一个变量的,对于这块代码,或者说被赋给变 ...

  5. 【java8新特性】——lambda表达式与函数式接口详解(一)

    一.简介 java8于2014年发布,相比于java7,java8新增了非常多的特性,如lambda表达式.函数式接口.方法引用.默认方法.新工具(编译工具).Stream API.Date Time ...

  6. java8(1)--- lambda

    项目马上切java8了,之前对于java8的东西都是东打一棒西打一锤的了解了些.这次搜集整理了下,从lambda到stream相关的API等. 1.Lambda和匿名内部类 Lambda 是一个匿名的 ...

  7. 夯实Java基础(二十二)——Java8新特性之Lambda表达式

    1.前言 Java 8于14年发布到现在已经有5年时间了,经过时间的磨练,毫无疑问,Java 8是继Java 5(发布于2004年)之后的又一个非常最重要的版本.因为Java 8里面出现了非常多新的特 ...

  8. Java8函数式接口与Lambda表达式

    摘要 何为函数式接口? 什么是lambda表达式,lambda表达式的本质: 函数式接口与lambda表达式的联系:lambda是实现函数式接口的一个快捷方式,可以作为函数式接口的一个实例: 常用Ja ...

  9. java8新特性之lambda表达式--超级详细版本

    java8新特性之lambda表达式 1.什么是lambda表达式?为什么用它? 2. 为什么Java需要lambda表达式? 3. lambda表达式的语法 4.函数式接口 4.1 什么是函数式接口 ...

最新文章

  1. 循环IRNNv2Layer实现
  2. Android shape 绘制左右 或者上下的渐变色
  3. 《C#精彩实例教程》小组阅读11 -- C#结构与类
  4. 分享:Svg文件转换为图片(调用 Inkscape 命令行)
  5. tomcat自动重启脚本
  6. FormsAuthentication详解
  7. ADB命令行控制界面开关
  8. spring mvc DispatcherServlet详解之interceptor和filter的区别
  9. python标识符和关键字_Python标识符和关键字资料解析
  10. P2597 [ZJOI2012]灾难(倍增LCA+拓扑排序)
  11. ctf镜子里面的世界_帮大爷干活,他送了我一只鞋子和一手套,又不能穿拿来做什么?哈哈哈|叶子|镜子|虫子|鞋子|棺材...
  12. 查看linux是否为虚拟机,以及其它信息,cpu,主机型号,主板型号等
  13. 杭电1879继续畅通工程
  14. 股票数据分析查询接口,股票数据接口,沪深港股,股票api查询
  15. 机器学习之多项式拟合
  16. 金字塔固定资产管理软件_目前常用固定资产管理软件有哪些?
  17. Google Java Style Guide
  18. hackinglab-脚本关10——基情燃烧的岁月
  19. NTL密码算法开源库——大整数ZZ类(一)
  20. 实现带附件格式的业务服务质量周报邮件

热门文章

  1. 信息化项目甲方采购的准备与实施
  2. 016.OpenStack及云计算(面试)常见问题
  3. Java设计模式学习总结(7)——结构型模式之适配器模式
  4. 疯狂软件对Oracle放弃Java EE的看法
  5. python读取文件名有中文_[请教]python的中文文件名处理
  6. 定量库存控制模型_供应链分析:关于库存管理的预测功能(1)
  7. 计算机学院 迎新口号,清华大学迎新标语
  8. 不能忽视 php warning
  9. 电视节目《宅男改变世界》
  10. Mysql-5.5+Heartbeat-3.0.5+DRBD