close
Warning:
Can't synchronize with repository "(default)" (Unsupported version control system "svn": /usr/lib/python2.7/dist-packages/libsvn/_fs.so: failed to map segment from shared object: Cannot allocate memory). Look in the Trac log for more information.
- Timestamp:
-
Jul 10, 2008, 4:36:22 PM (17 years ago)
- Author:
-
waue
- Comment:
-
--
Legend:
- Unmodified
- Added
- Removed
- Modified
-
|
v4
|
v5
|
|
| 1 | | [[PageOutline]] |
| | 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 = new GenericFoo<!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 |