2011-08-06 185 views
3

我遇到了泛型的問題。我定義了下面的靜態方法:Java泛型集合懷疑

public static <E extends Number> List<E> group(E ... numbers) { 
    return Arrays.asList(numbers); 
} 

我明白爲什麼這個工程:

List<Integer> ints = group(1, 2, 3); 

但是我有我的方法簽名更改爲使這項工作:

List<Number> ints = group(1, 2, 3); 

或者我應該只是將指定數字類型的組方法稱爲:

List<Number> ints = MyClass.<Number>group(1, 2, 3); 

在此先感謝。

回答

2

您需要明確指定Number作爲類型參數,因爲你建議。

List<Number> ints = MyClass.<Number>group(1, 2, 3); 
+3

另一個選擇是使用'List <?擴展Number> ints = ...;' – Jeremy

2

您將無法獲得List<Number>

如果您的方法group(1,2,3)返回List<Integer>,並且您表示該工作,那麼此表達式的類型爲List<Integer>

List<Integer>不是 a List<Number>。繼承意味着專業化,所以如果你的List<Integer>是一種List<Number>,你可以添加Double到你的List<Integer>(因爲超類可以這樣做,子類也可以)。這是錯誤的。 這不是鑄造問題,它只是推遲你的編譯問題到運行時。這個問題對於人類來說是合乎邏輯和相當矛盾的,但這就是收集和繼承的工作方式。

所以,如果你真的想要得到一個List<Number>我建議你定義第二個方法:

public static List<Number> groupAsNumbers(Number ... numbers) { 
    return Arrays.asList(numbers); 
} 

問候, 斯特凡

+0

只是要清楚,在Java'名單'不延長'名單'。如果你的方法返回'List ',那麼使用'Number'作爲變量類型的正確方法是'List <?擴展Number>'',它告訴編譯器你真的*想要一個以'Number'爲基數的項目列表,而不僅僅是靜態類型爲Number的實例。 – Jeremy

+0

感謝您的完成。 @傑勒米海勒。你是對的List <?擴展Number>是兩個列表的超類型。 – Snicolas