Changes between Version 4 and Version 5 of Generic
- Timestamp:
- Jul 10, 2008, 4:36:22 PM (17 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
Generic
v4 v5 1 [[Page Outline]]1 [[PageLayout]] 2 2 當您定義類別時,發現到好幾個類別的邏輯其實都相同,就只是當中所涉及的型態不一樣時,使用複製、貼上、取代的功能來撰寫程式只是讓您增加不必要的檔案管理困擾。 3 3 … … 345 345 [[BR]] 346 346 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]] 354 354 [[BR]] 355 355 356 356 現在您有這麼一個需求,您希望有一個參考名稱foo可以接受所有下面的實例(List、Map或List介面以及其實介面的相關類別,在J2SE 5.0中已經針對泛型功能作了改寫,在這邊仍請將之當作介面就好,這是為了簡化說明的考量):[[BR]][[BR]] 357 357 358 '''foo = new GenericFoo<!ArrayList>();359 foo = new GenericFoo<!LinkedList>();'''[[BR]][[BR]]358 '''foo = new !GenericFoo<!ArrayList>(); 359 foo = new !GenericFoo<!LinkedList>();'''[[BR]][[BR]] 360 360 361 361 簡單的說,實例化型態持有者時,它必須是實作List的類別或其子類別,要宣告這麼一個參考名稱,您可以使用 '?' 通配字元,並使用"extends"關鍵字限定型態持有者的型態,例如[[BR]] 362 362 [[BR]] 363 363 364 ''' GenericFoo<? extends List> foo = null;365 foo = new GenericFoo<!ArrayList>();364 '''!GenericFoo<? extends List> foo = null; 365 foo = new !GenericFoo<!ArrayList>(); 366 366 ..... 367 foo = new GenericFoo<!LinkedList>();367 foo = new !GenericFoo<!LinkedList>(); 368 368 ....'''[[BR]] 369 369 [[BR]] … … 374 374 [[BR]] 375 375 376 ''' GenericFoo<? extends List> foo = newGenericFoo<!HashMap>();'''[[BR]]376 '''!GenericFoo<? extends List> foo = new !GenericFoo<!HashMap>();'''[[BR]] 377 377 378 378 上面這段程式編譯器會回報以下的錯誤: … … 388 388 [[BR]] 389 389 390 public void showFoo( GenericFoo foo) {[[BR]]390 public void showFoo(!GenericFoo foo) {[[BR]] 391 391 // 針對List而制定的內容[[BR]] 392 392 }[[BR]] … … 394 394 395 395 您當然不希望任何的型態都可以傳入showFoo()方法中,您可以使用以下的方式來限定,例如: 396 '''public void showFoo( GenericFoo<? extends List> foo) {[[BR]]396 '''public void showFoo(!GenericFoo<? extends List> foo) {[[BR]] 397 397 398 398 }'''[[BR]] … … 400 400 401 401 402 這麼一來,如果有粗心的程式設計人員傳入了您不想要的型態,例如 GenericFoo<Boolean>型態的實例,則編譯器都會告訴它這是不可行的,在宣告名稱時如果指定了<?>而不使用"extends",則預設是允許Object及其下的子類,也就是所有的Java物件了,那為什麼不直接使用GenericFoo宣告就好了,何必要用GenericFoo<?>來宣告?使用通配字元有點要注意的是,透過使用通配字元宣告的名稱所參考的物件,您沒辦法再對它加入新的資訊,您只能取得它的資訊或是移除它的資訊,例如:402 這麼一來,如果有粗心的程式設計人員傳入了您不想要的型態,例如!GenericFoo<Boolean>型態的實例,則編譯器都會告訴它這是不可行的,在宣告名稱時如果指定了<?>而不使用"extends",則預設是允許Object及其下的子類,也就是所有的Java物件了,那為什麼不直接使用!GenericFoo宣告就好了,何必要用!GenericFoo<?>來宣告?使用通配字元有點要注意的是,透過使用通配字元宣告的名稱所參考的物件,您沒辦法再對它加入新的資訊,您只能取得它的資訊或是移除它的資訊,例如: 403 403 {{{ 404 404 #!java