程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 也說Java的雙括符初始化:其實就是令人費解的不規范代碼

也說Java的雙括符初始化:其實就是令人費解的不規范代碼

編輯:關於JAVA

初看 cgaolei 翻譯的 Java技巧之雙括弧初始化 一文,走馬觀花,只知用法,未細看後面的解釋。蔚為驚艷,心裡想 Java 竟然有這麼神奇的語法而一直未得知。因為在初始化集合時確實方便不少。原來做某些測試要初始化集合時會用到 commons-lang 包和 JDK 的 Arrays 工具類,現在知道可以這麼用了:

01.Map map = new HashMap() {{
02.        put("Name", "Unmi");
03.        put("QQ", "1125535");
04.}};
05.
06.List stooges = new ArrayList() {{
07.        add("Larry");
08.        add("Moe");
09.        add("Curly");
10.}};

看起來都是在一條語句裡完成,而不需要分步驟寫成:

1.Map map = new HashMap();
2.map.put("Name","Unmi");
3.map.put("QQ","1125535");

一不小心沒好好理解的人可能以為它是什麼特別的語法,關鍵是大括號連一塊了,原作者也是在故作姿態,美其名曰:雙括弧語法(double-brace syntax)。真是亂花漸欲迷人眼,其實就是匿名類加初始塊。該文有解釋:第一層括弧 實際是定義了一個內部匿名類 (Anonymous Inner Class),第二層括弧 實際上是一個實例初始化塊 (instance initializer block),這個塊在內部匿名類構造時被執行。

那怎麼去更好理解它呢?如果我們寫成如下的方式應該會更好理解吧,提個技巧,在 Eclipse 中對第一段代碼按下 Ctrl + Shift + F 就如下了:

1.Map map = new HashMap() {
2.    {
3.        put("Name", "Unmi");
4.        put("QQ", "1125535");
5.    }
6.};

其實就是匿名類啊,會創建出一個 HashMap 的子類來,匿名類中一個 {} 括起來的初始化塊,裡面自然可放置初始化代碼。{} 塊中的代碼編譯後會放到 <init>(),也就是構造方法中去,所以可用來初始化實例。如果是寫在 TestDoubleBrace 類中,編譯後你會看到會生成 TestDoubleBrace$1.class 文件,反編譯該文件內容是:

01.final class com.unmi.TestDoubleBrace$1 extends java.util.HashMap{ //創建了一個 HashMap 的子類 TestDoubleBracke$1
02.com.unmi.TestDoubleBrace$1();
03.  Code:
04.   0:   aload_0
05.   1:   invokespecial   #8; //Method java/util/HashMap."<init>":()V   //{} 中的代碼放到了構造方法中去了
06.   4:   aload_0
07.   5:   ldc     #10; //String Name
08.   7:   ldc     #12; //String Unmi
09.   9:   invokevirtual   #14; //Method put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
10.   12:  pop
11.   13:  aload_0
12.   14:  ldc     #18; //String QQ
13.   16:  ldc     #20; //String 1125535
14.   18:  invokevirtual   #14; //Method put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
15.   21:  pop
16.   22:  return
17.
18.}

所以說白了,什麼雙括弧語法啊,就是代碼寫得不規范,才使得那麼的令人費解。如果還不能理解,再列兩個慣用代碼來:

01.JFrame frame = new JFrame();
02.frame.addMouseListener(new MouseAdapter() {
03.    public void mouseClicked(MouseEvent e) {
04.        // do womething here.
05.    }
06.});
07.
08.Thread thread = new Thread() {{ // 也學著樣把大括號也連一塊寫了
09.        this.setName("作業處理線程");
10.    }// 如果不重新定義 run() 方法,那麼後面那個大括號也能與這個並一塊
11.
12.    public void run() {
13.        // do something here.
14.    }
15.};
16.thread.start();

應該沒問題了吧,上面是事件監聽器和多線程常用的寫法,如果他不把大括號連在一起,而是規范的寫代碼,相信您一開始也不會對所謂的 Double Brace Syntax 有太多的困惑。要說這種初始化方法運用到集合中還挺方便的,只是無端的多了些匿名類。

剛開始我看到這種雙括符寫法也是把它奉若聖經,對它只一知半解,昨天在用 XStream 把一個對象生成 XML 文件時,其中有一個 List 屬性,我就借用了這種雙括符法來初始化元素,結果生成的 XML 文件走了樣,原因是 XStream 的 Converter 能處理 ArrayList,但無法很好的處理生成的 ArrayList 的匿名子類。因此才回頭認真的重新審視了一番這個所謂的雙括符初始化語法。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved