File tree 1 file changed +20
-2
lines changed
1 file changed +20
-2
lines changed Original file line number Diff line number Diff line change 4
4
5
5
读过上一篇之后,相信对Lambda表达式的语法以及基本原理有了一定了解。对于编写代码,有这些知识已经够用。本文将** 进一步区分Lambda表达式和匿名内部类在JVM层面的区别,如果对这一部分不感兴趣,可以跳过** 。
6
6
7
- # 不仅是匿名内部类的简写
7
+ # 不是匿名内部类的简写
8
8
9
9
经过第一篇的的介绍,我们看到Lambda表达式似乎只是为了简化匿名内部类书写,这看起来仅仅通过语法糖在编译阶段把所有的Lambda表达式替换成匿名内部类就可以了。但实时并非如此。在JVM层面,Lambda表达式和匿名内部类有着明显的差别。
10
10
@@ -79,7 +79,7 @@ public class MainLambda {
79
79
12 : invokevirtual #5 // Method java/lang/Thread.start:()V
80
80
15 : return
81
81
82
- private static void lambda$main$0 (); /* Lambda表达式变成了主类的私有方法 */
82
+ private static void lambda$main$0 (); /* Lambda表达式被封装成主类的私有方法 */
83
83
Code :
84
84
0 : getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream;
85
85
3 : ldc #7 // String Lambda Thread run()
@@ -91,6 +91,24 @@ public class MainLambda {
91
91
92
92
反编译之后我们发现Lambda表达式被封装成了主类的一个私有方法,并通过* invokedynamic* 指令进行调用。
93
93
94
+ ## 推论,this引用的意义
94
95
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
95
113
96
114
You can’t perform that action at this time.
0 commit comments