Skip to content

Commit 3fff60e

Browse files
committed
添加Lambda表达式中this引用的意义
1 parent 688634b commit 3fff60e

File tree

1 file changed

+20
-2
lines changed

1 file changed

+20
-2
lines changed

2-Labmda and Anonymous Classes(II).md

+20-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
读过上一篇之后,相信对Lambda表达式的语法以及基本原理有了一定了解。对于编写代码,有这些知识已经够用。本文将**进一步区分Lambda表达式和匿名内部类在JVM层面的区别,如果对这一部分不感兴趣,可以跳过**
66

7-
# 不仅是匿名内部类的简写
7+
# 不是匿名内部类的简写
88

99
经过第一篇的的介绍,我们看到Lambda表达式似乎只是为了简化匿名内部类书写,这看起来仅仅通过语法糖在编译阶段把所有的Lambda表达式替换成匿名内部类就可以了。但实时并非如此。在JVM层面,Lambda表达式和匿名内部类有着明显的差别。
1010

@@ -79,7 +79,7 @@ public class MainLambda {
7979
12: invokevirtual #5 // Method java/lang/Thread.start:()V
8080
15: return
8181

82-
private static void lambda$main$0(); /*Lambda表达式变成了主类的私有方法*/
82+
private static void lambda$main$0(); /*Lambda表达式被封装成主类的私有方法*/
8383
Code:
8484
0: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream;
8585
3: ldc #7 // String Lambda Thread run()
@@ -91,6 +91,24 @@ public class MainLambda {
9191

9292
反编译之后我们发现Lambda表达式被封装成了主类的一个私有方法,并通过*invokedynamic*指令进行调用。
9393

94+
## 推论,this引用的意义
9495

96+
既然Lambda表达式不是内部类的简写,那么Lambda内部的`this`引用也就跟内部类对象没什么关系了。在Lambda表达式中`this`的意义跟在表达式外部完全一样。因此下列代码将输出两遍`Hello Hoolee`,而不是两个引用地址。
97+
98+
```Java
99+
public class Hello {
100+
Runnable r1 = () -> { System.out.println(this); };
101+
Runnable r2 = () -> { System.out.println(toString()); };
102+
public static void main(String[] args) {
103+
new Hello().r1.run();
104+
new Hello().r2.run();
105+
}
106+
public String toString() { return "Hello Hoolee"; }
107+
}
108+
```
109+
110+
## 参考文献
111+
112+
http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-final.html
95113

96114

0 commit comments

Comments
 (0)