Changes between Version 4 and Version 5 of Generic


Ignore:
Timestamp:
Jul 10, 2008, 4:36:22 PM (16 years ago)
Author:
waue
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Generic

    v4 v5  
    1 [[PageOutline]]
     1[[PageLayout]]
    22當您定義類別時,發現到好幾個類別的邏輯其實都相同,就只是當中所涉及的型態不一樣時,使用複製、貼上、取代的功能來撰寫程式只是讓您增加不必要的檔案管理困擾。
    33
     
    345345[[BR]]
    346346
    347 '''GenericFoo<Integer> foo1 = null;[[BR]]
    348 
    349 GenericFoo<Boolean> foo2 = null;'''[[BR]]
    350 
    351  
    352 
    353 那麼 foo1 就只接受GenericFoo<Integer>的實例,而foo2只接受GenericFoo<Boolean>的實例。[[BR]]
     347'''!GenericFoo<Integer> foo1 = null;[[BR]]
     348
     349!GenericFoo<Boolean> foo2 = null;'''[[BR]]
     350
     351 
     352
     353那麼 foo1 就只接受!GenericFoo<Integer>的實例,而foo2只接受!GenericFoo<Boolean>的實例。[[BR]]
    354354[[BR]]
    355355
    356356現在您有這麼一個需求,您希望有一個參考名稱foo可以接受所有下面的實例(List、Map或List介面以及其實介面的相關類別,在J2SE 5.0中已經針對泛型功能作了改寫,在這邊仍請將之當作介面就好,這是為了簡化說明的考量):[[BR]][[BR]]
    357357
    358 '''foo = new GenericFoo<!ArrayList>();
    359 foo = new GenericFoo<!LinkedList>();'''[[BR]][[BR]]
     358'''foo = new !GenericFoo<!ArrayList>();
     359foo = new !GenericFoo<!LinkedList>();'''[[BR]][[BR]]
    360360
    361361簡單的說,實例化型態持有者時,它必須是實作List的類別或其子類別,要宣告這麼一個參考名稱,您可以使用 '?' 通配字元,並使用"extends"關鍵字限定型態持有者的型態,例如[[BR]]
    362362[[BR]]
    363363
    364 '''GenericFoo<? extends List> foo = null;
    365 foo = new GenericFoo<!ArrayList>();
     364'''!GenericFoo<? extends List> foo = null;
     365foo = new !GenericFoo<!ArrayList>();
    366366.....
    367 foo = new GenericFoo<!LinkedList>();
     367foo = new !GenericFoo<!LinkedList>();
    368368....'''[[BR]]
    369369[[BR]]
     
    374374[[BR]]
    375375
    376 '''GenericFoo<? extends List> foo = new GenericFoo<!HashMap>();'''[[BR]]
     376'''!GenericFoo<? extends List> foo = new !GenericFoo<!HashMap>();'''[[BR]]
    377377
    378378上面這段程式編譯器會回報以下的錯誤:
     
    388388[[BR]]
    389389
    390 public void showFoo(GenericFoo foo) {[[BR]]
     390public void showFoo(!GenericFoo foo) {[[BR]]
    391391     // 針對List而制定的內容[[BR]]
    392392}[[BR]]
     
    394394
    395395您當然不希望任何的型態都可以傳入showFoo()方法中,您可以使用以下的方式來限定,例如:
    396 '''public void showFoo(GenericFoo<? extends List> foo) {[[BR]]
     396'''public void showFoo(!GenericFoo<? extends List> foo) {[[BR]]
    397397
    398398}'''[[BR]]
     
    400400
    401401 
    402 這麼一來,如果有粗心的程式設計人員傳入了您不想要的型態,例如GenericFoo<Boolean>型態的實例,則編譯器都會告訴它這是不可行的,在宣告名稱時如果指定了<?>而不使用"extends",則預設是允許Object及其下的子類,也就是所有的Java物件了,那為什麼不直接使用GenericFoo宣告就好了,何必要用GenericFoo<?>來宣告?使用通配字元有點要注意的是,透過使用通配字元宣告的名稱所參考的物件,您沒辦法再對它加入新的資訊,您只能取得它的資訊或是移除它的資訊,例如:
     402這麼一來,如果有粗心的程式設計人員傳入了您不想要的型態,例如!GenericFoo<Boolean>型態的實例,則編譯器都會告訴它這是不可行的,在宣告名稱時如果指定了<?>而不使用"extends",則預設是允許Object及其下的子類,也就是所有的Java物件了,那為什麼不直接使用!GenericFoo宣告就好了,何必要用!GenericFoo<?>來宣告?使用通配字元有點要注意的是,透過使用通配字元宣告的名稱所參考的物件,您沒辦法再對它加入新的資訊,您只能取得它的資訊或是移除它的資訊,例如:
    403403{{{
    404404#!java