背景
這幾天重溫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做的假設是否正確,后面深入學習以后再做斷言。