2009-07-19 94 views
2

考慮以下代碼:Java的泛型方法問題

public <T> List<T> meth(List<?> type) 
{ 
    System.out.println(type); // 1 
    return new ArrayList<String>(); // 2 
} 

它不會在第2行編譯,說是要求清單。

現在,如果它改爲:

public <T> List<?> meth(List<T> type) 
{ 
    System.out.println(type); // 1 
    return new ArrayList<String>(); // 2 
} 

它編譯。爲什麼?我認爲使用通配符聲明泛型類型和使用通配符的區別在於,使用通配符時,不能向集合添加新元素。爲什麼<?>允許返回List的子類型?我在這裏錯過了一些東西,明確的規則是什麼以及它如何被應用?

+0

你最初的目標是什麼?你想用你的方法完成什麼? – akarnokd 2009-07-19 14:09:13

+0

沒有什麼,這不是一個項目的一部分,我只是想了解java的通用方法。我'現在閱讀這個http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf – andandandand 2009-07-19 14:11:17

回答

4

區別在於返回類型聲明。 List<String>不是List<T>的子類型,但它是List<?>的子類型。

List<?>使得關於它的類型變量沒有假設,所以下面的語句是有效的:

List<?> l0 = new ArrayList<String>(); 
List<?> l1 = new ArrayList<Object>(); 
List<? extends Number> ltemp = null; 
List<?> l2 = ltemp; 

List<T>假設類型參數將在客戶端的情況下(例如使用類型)來解決,當你宣佈它作爲List<String>List<Object>。在方法體內,你也不能對它做任何假設。

1

在第一種情況下,T不一定是String的超類。如果您選擇一個TInteger並調用該方法,則會失敗;所以它不會編譯。然而,第二個肯定會編譯,任何ArrayList<String>是有效的List東西

1

如前所述,String不是T的子類型,所以它不起作用。但是,這段代碼的工作原理如下:

public <T> List<T> meth(List<?> type) 
{ 
    System.out.println(type); // 1 
    return new ArrayList<T>(); // 2 
} 

並且更多地是在想你想要什麼,我想。