2013-12-14 82 views
1

以下幾段代碼有什麼不同?Java泛型:列表<E>和列表<?>之間有區別嗎?

public static <E> void printElements(List<E> list) { 
    for (E elem : list) { 
     System.out.println(elem); 
    } 
} 

public static void printElements(List<?> list) { 
    for (Object elem : list) { 
     System.out.println(elem); 
    } 
} 

如果是的話,可以有人解釋的差異以及何時使用什麼呢?

+2

這已問過很多次了,爲什麼你不搜索它的網站? – SJuan76

+1

嘗試調用'list.add',你會注意到它的區別。 –

+0

爲了公平起見,「重複」實際上都不是其中之一。 OP在詢問有關這些問題的細微差別。 –

回答

0

雖然它不直觀,但有一點不同。我建議閱讀the java standard tutorial瞭解更多詳情。

基本上,兩者是不同的和不兼容的類型。 List<E>可以存儲擴展,子類或實際上是E類型的對象,但它是它自己的類型。即使您可以將String添加到List<Object>,也不能參考List<Object>參考中的List<String>

List<?>意味着它是一個列表引用,可以引用它的任何參數化引用。 A List<?>可以指代List<String>List<Integer>。當它受到某個接口或類的限制時,它非常有用。例如,下面的第一種方法(改編自java標準教程)將僅需要List<Number>,而不是像List<Double>List<Integer>

public static double sumOfList(List<Number> list) { 
    double s = 0.0; 
    for (Number n : list) 
     s += n.doubleValue(); 
    return s; 
} 

但是使用通配符下面的代碼可以採取List<Double>List<Integer>。它更靈活。

public static double sumOfList(List<? extends Number> list) { 
    double s = 0.0; 
    for (Number n : list) 
     s += n.doubleValue(); 
    return s; 
} 
+0

但是' double sumOfList(List list)'將帶有任何類型參數的列表,這是OP詢問的內容。 –

+0

但它不是類型安全的。如果你只是說列表,那麼你可以傳遞它一個列表,你可能會得到一個基於你的方法的運行時異常。但是一個List <?擴展Number>確保參數化類型是您的方法可以使用的東西。 – rapidclock

0

第一條語句使用了Bounded Type ParamaterE,而第二條語句使用了Wildcard Parameter。第一條語句是有界限的,因爲它「限制可以在參數化類型中用作類型參數的類型」。就你而言,?表示它是某種類型的列表,但我們不知道它是什麼。它是無限的類型。

+2

它在兩種情況下都是一樣的。也沒有'E'的限制。 –

+0

對於這個例子,是的。它僅在編譯時檢查時有所幫助,因爲'E'在使用時會受到參數化類型的限制。沒有辦法將'?'綁定到一個類型。 –

+1

我覺得你很迷惑「綁定」和「綁定」。 –

相關問題