背景
这几天重温Java,发现Java在嵌套类型这里提供的特性比较多,结合自身对C#中匿名委托的理解,我大胆的做了一个假设:Java的字节码只支持静态嵌套类,内部类、局部内部类和匿名局部内部类都是编译器提供的语法糖,这个假设目前没法验证(看不懂字节码),本文先来看一下C#是如何为我们提供的这种语法糖。
实验
测试代码
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace CSharpStudy 8 { 9 class Program 10 { 11 static void Main(string[] args) 12 { 13 int i = 0; 14 15 Action action1 = () => 16 { 17 System.Console.WriteLine(i); 18 }; 19 20 i++; 21 22 Action action2 = () => 23 { 24 System.Console.WriteLine(i); 25 }; 26 27 i++; 28 29 action1(); 30 action2(); 31 } 32 } 33 }
输出
使用Reflector进行反编译
1 private static void Main(string[] args) 2 { 3 <>c__DisplayClass2 CS$<>8__locals3 = new <>c__DisplayClass2(); 4 CS$<>8__locals3.i = 0; 5 Action action1 = new Action(CS$<>8__locals3.<Main>b__0); 6 CS$<>8__locals3.i++; 7 Action action2 = new Action(CS$<>8__locals3.<Main>b__1); 8 CS$<>8__locals3.i++; 9 action1(); 10 action2(); 11 }
public void <Main>b__0() { Console.WriteLine(this.i); } public void <Main>b__1() { Console.WriteLine(this.i); }
备注
应该一看就明白了,也可以想象Java也是这么处理的(匿名局部内部类),局部内部类和内部类不过是一种类似的语法糖机制,最近发现.Net、Java和Go提供的闭包机制都是基于编译器实现的,这和动态语言的闭包机制有明显的不同。
不知道我对Java做的假设是否正确,后面深入学习以后再做断言。