隨筆-199  評論-203  文章-11  trackbacks-0

          原文地址:http://www.c2.com/cgi/wiki?DoubleBraceInitialization

                  這是我在JavaIdioms(http://www.c2.com/cgi/wiki?JavaIdioms)上看到一個Java使用技巧。使用Java這么多年了,也還是頭一次看到,還很實用。別看這小技巧好像很簡單,但保證你不會在任何一書Java教材上看到,因為它不是一個真正的語法規范,而是一個語法的用法變種。小技巧還蘊含著Java的深層知識,就是身經百戰的老手也不一定能說出其中奧妙。

          翻譯正文:

          由于Java語言的集合框架中(collections, 如list, map, set等)沒有提供任何簡便的語法結構,這使得在建立常量集合時的工作非常繁索。每次建立時我們都要做:

          1. 定義一個臨時的集合類變量
          2. 建立一個空集合的實例,然后賦值給變量
          3. 將數據放入集合中
          4. 最后將集合做為參數傳遞給方法

          例如,要將一個Set變量傳給一個方法:

          Java代碼 復制代碼
          1. Set<String> validCodes = new HashSet<String>();   
          2. validCodes.add("XZ13s");   
          3. validCodes.add("AB21/X");   
          4. validCodes.add("YYLEX");   
          5. validCodes.add("AR2D");   
          6. removeProductsWithCodeIn(validCodes);  

          也可以用靜態初始的方法

          Java代碼 復制代碼
          1. private static final Set<String> validCodes = new HashSet<String>();   
          2. static {   
          3.        validCodes.add("XZ13s");   
          4.        validCodes.add("AB21/X");   
          5.        validCodes.add("YYLEX");   
          6.        validCodes.add("AR2D");   
          7. }  

          其實,還有簡結的方法,我們可以用雙括弧語法(double-brace syntax)建立并初始化一個新的集合:

          Java代碼 復制代碼
          1. private static final Set<String> VALID_CODES = new HashSet<String>() {{   
          2.        add("XZ13s");   
          3.        add("AB21/X");   
          4.        add("YYLEX");   
          5.        add("AR2D");   
          6. }};  

          或者

          Java代碼 復制代碼
          1. removeProductsWithCodeIn(new HashSet<String>() {{   
          2.        add("XZ13s");   
          3.        add("AB21/X");   
          4.        add("YYLEX");   
          5.        add("AR5E");   
          6. }});  

          第一層括弧 實際是定義了一個內部匿名類 (Anonymous Inner Class),第二層括弧 實際上是一個實例初始化塊 (instance initializer block),這個塊在內部匿名類構造時被執行。這個塊之所以被叫做“實例初始化塊”是因為它們被定義在了一個類的實例范圍內。這和“靜態初始化塊 (static initialzer)”不同,因為這種塊在定義時在括弧前使用了static關鍵字,因此它的和類在同一個范圍內的,也就是說當類加載時就會被執行(更詳情,可參考Java語言規范http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.6 )。實例初始化塊中可以使用其容器范圍內的所有方法及變量,但特別需要注意的是實例初始化塊是在構造器之前運行的。


          這種方法只適用于不是final的類,因為final類是無法建立內部匿名子類,好在集合類都沒有這個限制。因此,這種方法還可以被用來初始化其它任何對象,比如一個GUI對象:

          Java代碼 復制代碼
          1. add(new JPanel() {{   
          2.        setLayout(...);   
          3.        setBorder(...);   
          4.        add(new JLabel(...));   
          5.        add(new JSpinner(...));   
          6. }});  

           這樣建立的內部匿名類的實例中包函它容器對像的引用。如果串行化(serialization)這個集合同時也會串行化它的內部類.

          posted on 2009-07-14 16:47 Werther 閱讀(1786) 評論(4)  編輯  收藏 所屬分類: 10.Java

          評論:
          # re: Java技巧之雙括弧初始化 2009-07-14 19:21 | 日月雨林@gmail.com
          這個方法我經常用! 很早就開始用了!  回復  更多評論
            
          # re: Java技巧之雙括弧初始化 2009-07-14 21:40 | ecbeta
          說實話理解不是問題. 只是沒有想到這樣用. 匿名內部類經常使用. 但是沒有想到有這樣的用法. 這樣可以推廣到任何一種類了 除非那種final的.  回復  更多評論
            
          # re: Java技巧之雙括弧初始化 2009-07-15 10:47 | 于翔
          見識了  回復  更多評論
            
          # re: Java技巧之雙括弧初始化 2013-08-12 16:40 | dohkoos
          Initializer Build idiom。  回復  更多評論
            
          主站蜘蛛池模板: 同仁县| 江西省| 曲周县| 栾川县| 寿宁县| 双峰县| 墨江| 高陵县| 楚雄市| 远安县| 吉木乃县| 肥东县| 平谷区| 民县| 井陉县| 蛟河市| 兴化市| 安阳县| 安阳市| 利辛县| 白山市| 本溪| 苗栗市| 雅安市| 金溪县| 秦皇岛市| 彩票| 九龙县| 长葛市| 彭水| 新化县| 弥勒县| 肇源县| 太白县| 霞浦县| 黄冈市| 博湖县| 商都县| 周宁县| 东平县| 兖州市|