2013-10-10 72 views
1

我是新來的這些泛型類型。在下面的代碼中,我創建了一個接受擴展「String」的項目列表的方法。通用擴展不能添加相同類型

我的問題是? - 當列表可以分配一個新的列表,爲什麼不能添加一個字符串「測試」......它給我一個編譯錯誤。

public class Child { 
    public void takeList(List<? extends String> list){ 
     list = new ArrayList<String>(); 
     list.add("test"); 
    } 
} 

回答

1

因爲這不是與此相關的運行時類型。 list仍然是List<? extends String>類型,您恰好將其分配給new ArrayList<String>()。試想一下:

list = rand() ? new ArrayList<String>() : new ArrayList<NotString>(); 

編譯器不可能知道是否list.add("test")將是有效的 - 它纔有基礎上list編譯時類型決定。

請注意,實際上沒有任何擴展String,這是一個final類。

0

有一個微妙的區別。它需要一個包含一種類型的東西(擴展字符串的東西)的列表。該列表可能是String的子類,因此不能是String iyswim。見http://docs.oracle.com/javase/tutorial/java/generics/upperBounded.html上界有通配符。

如果是

 public void takeList(List<? *super* String> list){ 

然後,你可以添加字符串,因爲該列表是保證能夠接受的字符串。

0

當你有一個帶有通配符的變量和一個採用泛型類型參數的方法時,Java不能確保類型安全。它必須禁止此呼叫。例如,可以考慮List<? extends Animal>。您可能已經爲其分配了List<Dog>,但該變量可以分配爲List<Squid>。您不應該被允許將Dog添加到這樣的列表中。要調用add方法,請刪除通配符。

public void takeList(List<String> list){ 

此外,String is final,所以真的是沒有一點說? extends String