2009-07-08 81 views
14

不幸的是,我已經將Java編碼了大約五年了,而且我完全記不起以下代碼的工作原理。這是什麼構造函數調用以下雙括號?

我偶然發現了一個類似的例子,並將其分解爲這個。重點是評論下面的部分:我沒有得到構造函數表示法,後面跟着括號中的塊。不幸的是,我無法在Java文檔或使用Google中找到任何內容(我應該使用Google什麼字詞?)。

package syntaxtest; 

public class Main { 

    public static void main(String[] args) { 

     // What kind of notation is this? 
     MyTest tester = new MyTest() {{ 
      setName("John Johnson"); 
     }}; 

     System.out.println(tester.getName()); 
    } 
} 


class MyTest { 
    private String name; 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 
} 

因此,這裏是我的問題:

  1. 這是怎麼符號/語法叫什麼名字?
  2. 我可以在哪裏閱讀關於它的一些文檔?

我想/希望如果有人能爲我提供第一個問題的答案,我將能夠自己回答第二個問題。

要說清楚:我知道輸出是John Johnson;)但我不知道它爲什麼工作。

+0

當我第一次看到它在Usenet我不得不看它一會兒意識到發生了什麼事了。一旦你知道它是什麼,這是顯而易見的。 – 2009-07-08 19:43:38

+0

前段時間我看到了這個巧妙的技巧,但我也看到了很多免責聲明,說很容易打破它的東西/不是很可靠。如果我要嘗試使用它,我一定會考慮到A)我必須向每個人解釋它,以便從那時起查看代碼,並且B)我必須做一些研究瞭解使用這種模式的所有含義。 – 2009-07-08 20:20:53

回答

20

這被稱爲double brace initialization

第一支桿創建一個新的 AnonymousInnerClass,第二 聲明瞭一個實例初始化塊 當匿名內部 類被實例化時運行。這種類型的 初始化塊的正式的稱呼 的「實例初始化」,因爲它是 實例範圍類的 內聲明的 - 「靜態初始化」 是一個相關的概念,在這裏 關鍵字static是 前放置撐啓動該塊,並且其 作爲所述類裝入器完成加載 類(在 http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.6指定) 的初始化代碼塊可以使用任何 方法,字段和最後變量 在可用在類級儘快執行 包含範圍,但必須是 警惕 構造函數在 構造函數之前運行。

這隻適用於非最終 類,因爲它創建了一個 匿名子類。

14

讓我們佈局的代碼有點不同:

MyTest tester = new MyTest() { 
    { 
    setName("John Johnson"); 
    } 
}; 

你在這裏看到什麼叫雙括號初始化。你有一個MyTest類的匿名內部子類,以及一個初始化塊,它是一個包含構造對象時運行的代碼的塊。

通常情況下,您可以將這些代碼放入構造函數中,但由於匿名內部類不能具有構造函數,因此這是確保代碼在應該運行時的唯一方法。

話雖如此,但這樣做有點難看。有更好的方法。但是,我用它自己上一次,通常在下面的語句來創建一個不可變的映射:

final Map<String, Integer> textToInt = Collections.unmodifiableMap(new HashMap<String, Integer>() {{ 
    put("one", 1); 
    put("two", 2); 
    // etc 
}}); 

這將創建一個新的地圖,覆蓋它,增加了一些價值給它的初始化塊,並把它封裝在一張不可修改的地圖中。

-5
MyTest tester = new MyTest() {{ 
    setName("John Johnson"); 
}}; 

相同

MyTest tester = new MyTest(); 
tester.setName("John Johnson"); 
相關問題