2009-03-06 118 views

回答

16

因爲類型參數僅用於「輸出」位置,所以當您獲得其中一個時,您可以執行的操作沒有實際區別。另一方面,你可以使用作爲其中之一。

假設你有一個Enumeration<JarEntry> - 你不能把它傳遞給一個以Enumeration<ZipEntry>爲參數的方法。你可能把它傳遞給一個採取Enumeration<? extends ZipEntry>雖然。

當你有一個在輸入和輸出位置都使用type參數的類型時更有趣 - List<T>是最明顯的例子。以下是三個參數變化的方法示例。在每種情況下,我們都會嘗試從列表中獲取一個項目,然後再添加一個項目。

// Very strict - only a genuine List<T> will do 
public void Foo(List<T> list) 
{ 
    T element = list.get(0); // Valid 
    list.add(element); // Valid 
} 

// Lax in one way: allows any List that's a List of a type 
// derived from T. 
public void Foo(List<? extends T> list) 
{ 
    T element = list.get(0); // Valid 
    // Invalid - this could be a list of a different type. 
    // We don't want to add an Object to a List<String> 
    list.add(element); 
} 

// Lax in the other way: allows any List that's a List of a type 
// upwards in T's inheritance hierarchy 
public void Foo(List<? super T> list) 
{ 
    // Invalid - we could be asking a List<Object> for a String. 
    T element = list.get(0); 
    // Valid (assuming we get the element from somewhere) 
    // the list must accept a new element of type T 
    list.add(element); 
} 

欲瞭解更多詳情,請閱讀:

+0

一個ZipEntrySubclass像JarEntry(ZipFile.entries使用通配符的原因)? – 2009-03-06 11:35:21

+0

謝謝湯姆 - 將編輯我的答案:) – 2009-03-06 11:56:55

4

是,直接從sun generics tutorials之一:

這裏Shape是一個抽象類 三個子類:Circle,Rectangle, 和Triangle。

public void draw(List<Shape> shape) { 
    for(Shape s: shape) { 
    s.draw(this); 
    } 
} 

值得注意的是,平局() 方法只能在 形狀的列表來調用,不能在列表上叫做圓形,矩形,三角形和對 例如 。爲了讓方法 接受任何類型的形狀,它應該是 寫成如下:

public void draw(List<? extends Shape> shape) { 
    // rest of the code is the same 
} 
0

現在你剛剛走了,提醒我的東西,我希望我們在C#全球已經有超過。

除了鏈接提供的,有關於C#和Java中關係在回答這個問題的一些好的鏈接到這個話題:Logic and its application to Collections.Generic and inheritance

的選擇,其中包括: