2012-03-23 83 views
0

在Maurice Naftalin,Philip Wadler撰寫的「Java泛型和收集」一書中,我遇到了泛型限制,並提出了疑問。可能是書中的答案,但我認爲我很困惑。
在下面的代碼:
類型安全警告

List<List<?>> lists = new ArrayList<List<?>>(); 
lists.add(Arrays.asList(1,2,3)); 
lists.add(Arrays.asList("four","five")); 
assert lists.toString().equals("[[1, 2, 3], [four, five]]"); 

正如書中說,該嵌套通配符實例沒有問題,因爲第一個列表,它知道將包含列表類型的對象。

但我試着修改上面的代碼,並提出了一個警告和一個編譯時錯誤。我試圖做的:

List<?> sample= Arrays.asList(1,2,3,4.14); 
    List<List<?>> lists = new ArrayList<List<?>>(); 
    lists.add(Arrays.asList(1,2,3)); 
    lists.get(0).add(5); 
    lists.add(Arrays.asList("four","five")); 
    System.out.println(sample.toString()); 
    assert lists.toString().equals("[[1, 2, 3], [four, five]]"); 

我的問題是: 1)在第一行,如果我寫的:

List<?> sample= Arrays.asList(1,2,3); 

無警告這裏發出,但寫在前面的塊中,如果我寫:

List<?> sample= Arrays.asList(1,2,3,4.14); 

發出警告。爲什麼?

2)爲什麼會出現在第四行編譯時間錯誤:

lists.get(0).add(5); 

預先感謝。

+0

報告的警告和錯誤是什麼? – WhiteKnight 2012-03-23 10:30:36

回答

3

有一個編譯時異常,因爲lists.get(0)返回List<?>

你不知道這是什麼類型列表中,你知道你可以從它那裏得到的元素(這將是至少一個Object),但你不能把任何東西在它(因爲你不知道它會適合

,如果你寫的,而不是什麼會追加:

List<List<?>> lists = new ArrayList<List<?>>(); 
lists.add(new ArrayList<String>()); 
lists.get(0).add(5); 
lists.add(Arrays.asList("four","five")); 

你有一個ArrayList<String>和你想添加一個 數字在裏面。所以爲了避免這種錯誤(並且因爲驗證是在編譯時完成的),如果您不確定它是否可行,則不能添加內容。


關於你的警告,我沒有任何。

0

1) 這行不應該給出警告(當我嘗試它時不會發出警告)。你看到了哪個警告?

2) 由於lists.get(0)的類型是List<?>而不是List<Integer,因此存在編譯時錯誤。這意味着,編譯器不知道列表是否允許包含整數...

0

2)爲什麼會出現一個編譯時錯誤在第四行:

lists.get(0)。添加(5);

因爲您定義了List> lists = new ArrayList>(); 並且您試圖在列表中添加簡單整數5。這就是爲什麼,IDE給編譯錯誤。