2014-08-27 149 views
4

工作用一個例子解釋這個問題:Java泛型:無界通配符不與對象類型參數

public class DataWrapper<T> { 
    T data; 
}; 

DataWrapper<Object> obj1 = new DataWrapper<Object>(); 

List<DataWrapper<?>> anyDataList = Arrays.asList(obj1); //this doesn't work 

DataWrapper<Integer> objInt = new DataWrapper<Integer>(); 
anyDataList = Arrays.asList(obj1, objInt); //this work 

我不明白爲什麼「Arrays.asList(OBJ1)」不工作?

+4

升級到Java 8獲得更好的結果:) – 2014-08-27 19:36:28

+0

Java類型系統是相當困難的代碼,而無需一個IDE左右,這是肯定的。 – 2014-08-27 19:39:19

+0

確認:這個解釋在Java 8 – therealrootuser 2014-08-27 19:40:05

回答

9

當推斷泛型方法的類型參數時,Java 7很愚蠢(並非不是)。例如,它將使用聲明的參數類型來推斷類型,而不管方法調用的上下文。因此,在

Arrays.asList(obj1); 

類型參數會被推斷爲

DataWrapper<Object> 

方法的返回類型將被List<DataWrapper<Object>>這是沒有分配給一個List<DataWrapper<?>>

Arrays.asList(obj1, objInt); 

類型是從兩個參數推斷。兩者之間有共同的類型。在這種情況下,這是? extends Object。方法返回類型變爲List<DataWrapper<? extends Object>>,可指定給List<DataWrapper<?>>

在Java 8中,您發佈的內容是開箱即用的。在Java 7中,可以提供一個明確的類型參數,使其工作

List<DataWrapper<?>> anyDataList = Arrays.<DataWrapper<?>>asList(obj1); 
+0

+1中有效。你還可以爲使用Java 7的人提供解決方法嗎? – StriplingWarrior 2014-08-27 19:43:43

+1

@StriplingWarrior Yup補充道。謝謝! – 2014-08-27 19:45:13

+0

DataWrapper 可以分配給DataWrapper 。擴展這個邏輯,我預計這個通配符還可以用於二級嵌套類型參數:List >應該可以分配給List > – user1447561 2014-08-27 19:45:58