2013-02-20 85 views
2

我已經閱讀了很多關於這一點,我知道:差異<?>

List<Object> listOfObject = new ArrayList<TYPE>(); // (0) 
//can only work for TYPE == Object. 
//if TYPE extends Object (and thus objects of type TYPE are Objects), 
//this is not the same with Lists: List<Type> is not a List<Object> 

現在我讀過,以下是確定:

List undefinedList = new ArrayList<TYPE>(); // (1) 
//works for ANY type (except for primitives) 

而且

List<?> wildcardList = new ArrayList<TYPE>(); // (2) 
//also works for ANY type (except for primitives) 

然後:

List undefinedlist = new ArrayList(); //no TYPE specified 
undefinedList.add(new Integer(1)); //WORKS 
undefinedList.add(new String("string")); //WORKS 

但是:

List<?> wildcardList = new ArrayList<TYPE>(); //TYPE specified 
wildcardList.add(new TYPE(...)); //COMPILER ERROR 

例如:

List<?> wildcardList = new ArrayList<String>(); //TYPE specified 
wildcardList.add(new String("string")); //COMPILER ERROR: The method add(capture#1-of ?) in the type List<capture#1-of ?> is not applicable for the arguments (String) 

我不明白你爲什麼不能添加任何東西到wildcardList,因爲它的類型可以是任何東西。但是,爲什麼你可以添加到undefinedList? 他們似乎相同&顯示相同的行爲,給出(1)和(2)。

+0

與幾乎任何問題一樣。實際顯示「編譯器錯誤」實際上是什麼(錯誤文本)總是更好。 – billjamesdev 2013-02-20 15:25:05

+0

'?'不代表*任何*,但**未知**。 – m0skit0 2013-02-20 15:25:08

+2

[java泛型未綁定通配符vs原始類型](http:// stackoverflow。com/questions/14242174/java-generics-unbound-wildcard-vs-raw-type) – 2013-02-20 15:25:14

回答

0

「未定義」 List包含Object類型的列表,它是所有類型的父親,因此List不是類型安全的(是可以相互轉換)

這就是爲什麼:

List undefinedlist = new ArrayList<TYPE>(); //IS LIST OF OBJECTS 
undefinedList.add(new Integer(1)); //WORKS 
undefinedList.add(new String("string")); //WORKS 

好..工作!

+1

'對象'不是類型安全的?對不起,我不明白這一點。 – m0skit0 2013-02-20 15:26:16

+0

如果這是真的,那麼(0)和(1)之間有什麼區別? – joost 2013-02-20 15:27:32

+0

之間的區別是一個是零和另一個是1? @joost – 2013-02-20 15:28:00

0

List<?>類型是通用的:在列表的方法中將使用放置問號的任何類型。因此,您可以執行list.add(item),如果您創建了List<String>,它將只允許您輸入String。類型安全第一。

List<String> list = new List<String>(); 
list.add("A");    // <-- Correct 
list.add((Integer)10);  // <-- Error, it is a List of Strings 

在另一方面,List允許任何Object被擺在那裏。所以你可以製作一個List,把Giraffe放在那裏,然後再放一個Squid。它並不在意,如果你期望只有Giraffe對象在那裏,它可能是編程錯誤的根源。

List list = new List(); 
list.add("A");    // <-- Allowed 
list.add((Integer)10);  // <-- Also allowed, 
          // but now the list contains not only strings 
+0

這很清楚,但不是我的問題的答案。 – joost 2013-02-20 15:32:41

0

基本上,?在以下

List<?> wildcardList = new ArrayList<TYPE>(); 

意味着一些未知的(特定)型。因此,它不允許您將類似StringInteger的內容添加到某個未知類型的列表中,因爲泛型應該是類型安全的。

雖然在以下

List<Object> listOfObject = new ArrayList<TYPE>(); 

你可以因爲一切都是在Java中Object添加任何東西給它。所以它是類型安全的。

而且還與以下

List undefinedList = new ArrayList<TYPE>(); 

你告訴你不想有使用泛型的編譯器。這意味着您在undefinedList上調用的每個方法都將是非泛型的,因爲您已決定使用原始List。集合框架中所有容器的非泛型版本都被編寫爲Object(Java中的任何對象)。

+0

謝謝。然而,我沒有得到原始和通用的區別.. – joost 2013-02-20 15:47:32

+0

'List '(with'')是泛型的,而'List'(使用** no **' 2013-02-20 15:50:45

+0

這意味着它們都是不同的類?因爲:沒有提供任何類型參數,哪種類型將被使用? – joost 2013-02-20 15:57:45

2

List undefinedListList<?> wildcardList是不一樣的,因爲你發現你自己。第一種是原始類型,第二種是無界通配符。

,如果你想使用泛型類型使用無界通配符,但你不知道或不關心實際的類型參數是什麼。你不能把任何東西(空值除外)放到這個列表中,而你所知道的關於它的元素是它們擴展了Object(實際上List<?>List<? extends Object>相同)。無界通配符是有用的,因爲如果你會天真地宣稱什麼作爲List<Object>,你不能例如List<String>分配給它,而你可以指定一個List<String>List<?>

你應該(幾乎)從來沒有需要使用原類型,它們只適用於使用Java編寫的前5

1

清單代碼兼容性意味着,這是未知類型的列表 - 這樣你不會在創建時使用它(在你的例子),你通常會用它作爲方法參數。

public void printList(List<?> items) 

這可能重複的(任何)未知項列表:作爲方法的參數,如使用未綁定時,通配符只能真正有用的。在這種情況下,列表項目可以達到相同的目的,但客戶端可能會收到警告。

如果你有以下幾點:

public void printList(List<Object> items) 

那麼只有一個的Object列表可以處理 - 不是一個列表的字符串,證書等,只有對象。

看看Unbounded Wildcards - 它解釋了很好

1

List<?>讀爲一些未知類型的列表。作爲一名程序員,你不能對什麼類型做任何假設,也不能將任何東西放入除null之外的其他集合中。但是您可以放心,您的列表是安全類型的,因爲編譯器會爲您保證類型安全。

List基本上稱爲原始類型。也就是說它已經選擇了編譯器保證的類型安全。因此,您可以將任何類型的元素放入該List中以銷燬其不變量。不要再使用原始類型進行編碼。它們基本上支持向後兼容性,因爲Java已經進入開發的第二個十年了,因爲Sun將泛型引入表中,並且使用原始類型編寫了大量代碼,否則這些程序會中斷。

相關問題