2014-10-08 127 views
2

我想使用ArrayList的構造函數:ArrayList的類型推斷

ArrayList(Collection<? extends E> c) 

如下。

List<Integer> li = new ArrayList<>(); 

List<Number> ln = new ArrayList<>(li); // won't compile.. Type mismatch: cannot convert from ArrayList<Integer> to List<Number> 

我不明白編譯器錯誤。

但是,以下編譯正常。

List<Number> ln = new ArrayList<Number>(li); 

我在想什麼?使用java 7

+0

有人可以在Java8上試試這個嗎?也許目標類型推斷已被改進? – Thilo 2014-10-08 02:38:58

回答

0

這是「鑽石操作員」的限制。

List<Number> ln = new ArrayList<>(li); 

被擴大到

List<Number> ln = new ArrayList<Integer>(li); 

不編譯。

您可以通過更明確的解決這個問題:

List<Number> ln = new ArrayList<Number>(li); 
+1

這種擴張究竟如何發生?李是一個構造函數的參數。 – user2953113 2014-10-08 02:31:11

+0

@ user2953113:我不確定...但是'Integer'部分必須來自'li'(它必須與構造函數簽名相匹配,可用選項是'Integer','Number','' Object','Serializable','Comparable'。我想語言規範只是使用對象類型本身)。 – Thilo 2014-10-08 02:33:44

+0

瞭解擴展如何發生。構造函數中的E()鏈接到ArrayList 中的E.在li的情況下,E變爲Integer,並且ArrayList 變成ArrayList 。 – user2953113 2014-10-08 03:06:30

1

的問題是Java創建ArrayList類型<整數>的新對象。由於Integer與Number不完全相同,因此不能將其分配給List <Number>類型的變量。您必須使用通配符,像這樣:

List<Integer> li = new ArrayList<>(); 
List<? extends Number> ln = new ArrayList<>(li); 

這允許泛型類型整數,它擴展號碼的清單,被分配到類型列表的變量<數>。在這裏尋找更多的信息:http://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html

+1

java如何創建一個ArrayList ?這個邏輯是否記錄在某個地方? – user2953113 2014-10-08 02:35:30

+0

我不確定你在問什麼。如果您問爲什麼Java選擇創建ArrayList 而不是ArrayList ,這是因爲li的類型是ArrayList ,並且該語言從li的類型推斷出該類型。如果li的類型是List <?擴展Number>,那麼你就可以完成任務。 – user2503846 2014-10-08 02:45:02

+0

我應該補充說,你可以在構造函數的簽名中看到這個:ArrayList(Collection c)。在這種情況下,E來自li的通用類型。當li是List <?擴展Number>,E就是Number。 – user2503846 2014-10-08 02:47:18