2014-02-27 102 views
1

在另一個SO post說明,下面的例子被給定爲到OP的響應:Java泛型:實施例對SO

public static <E> void funct1(final List<E> list1, final E something) 
{ 
    list1.add(something); 
} 

public static void funct2(final List<?> list, final Object something) 
{ 
    list.add(something); // does not compile 
} 

我已驗證funct1編譯而funct2沒有。但是,我無法弄清楚爲什麼。

+1

我們不知道'list'是包含'Object'情況下一個'List'。 –

+0

什麼是編譯錯誤? – FatalError

回答

8

A List<?>是一個特定的未知類型的列表。編譯器不能在具有泛型類型參數的方法上調用,因爲不能保證類型安全。它可能是List<Integer>List<Foo>,並且不應該能夠向其添加Object。編譯器必須通過編譯器錯誤來阻止此調用,以保持泛型提供的類型安全性。

方法funct1編譯,因爲您總是可以將E添加到List<E>;它是相同的類型參考:E

+0

在這種情況下,什麼排除了類型推斷? – Schemer

+1

在'List '案件中沒有推斷的類型。 '?'通配符不會從要添加到List中的對象推斷出該類型。 '?'通配符意味着我們故意不知道或關心實際類型,只要它是一種特定類型即可。 – rgettman

4

rgettman是對的,但重要的是要聲明這不僅適用於List。它適用於所有通用類型。

如果使用通配符?聲明參數化類型的變量,則不能使用參數化類型爲任何內容聲明的相應類型變量,因爲您不知道它的值是什麼。但是,您可以使用null,因爲null可用於任何需要某種引用類型值的地方。

例如

public class Example { 
    public static void main(String[] str) throws Exception { 
     Parameterized<?> exp = new Parameterized<String>(); 
     // below won't compile 
     /* 
      exp.something("tried my best"); 
      exp.something(666); 
     */ 


     // below will compile 
     exp.something(null); 
    }  
} 
class Parameterized<T> { 
    public void something(T value) {} 
}