2011-04-23 90 views
1

另一個例子是相當複雜的,我不理解的事,我的問題是有點類似,但就像我說的更簡單,Java:不能泛型List <?擴展父> MYLIST

public List<? extends Parent> myfunction(List<? extends Parent> mylist){ 
     mylist.add(new Child()) ; //Doesn't Compile 
} 
+0

向我們展示瞭如何聲明子和父類。另外我會建議總是使用第一個大寫字母作爲任何類名。 – Boro 2011-04-23 11:44:26

回答

8

我相信你正在尋找一種方法,它需要一個列表,向它添加一些東西,然後返回列表。該列表是通用的,並且您希望返回類型與參數的類型相匹配。

這裏是你如何做到這一點,在一般情況下:

public <T extends Parent> List<T> myfunction(List<T> myList) { 
    ... // Add something to myList 
    return myList; 
} 

具體來說,你想添加到new Child()myList。這是行不通的。可以使用多種列表調用myfunction(),但如果列表是List<Parent>List<Child>,則只能添加new Child()。下面是不同類型的列表中的一個例子:

public static class Parent {} 
public static class Child extends Parent {} 
public static class OtherChild extends Parent {} 

public <T extends Parent> List<T> myfunction(List<T> myList) { 
    myList.add(new Child()); 
    return myList; 
} 

myfunction(new ArrayList<OtherChild>()); 

在最後一行,myfunction()被稱爲與OtherChild對象的名單。顯然,將一個Child對象添加到這樣的列表中是非法的。編譯器防止通過拒絕myfunction()

附錄的定義

如果你想myfunction()能夠將元素添加到myList你需要使用一個工廠(因爲Java不允許new T()其中T是一個類型參數 - 由於type erasure)。下面是如何myfunction()樣子:

public interface Factory<T> { 
    public T create(); 
} 

public <T extends Parent> List<T> myfunction(List<T> myList, 
              Factory<? extends T> factory) { 
    myList.add(factory.create()); 
    return myList; 
} 

而現在,它的用法:

public static class ChildOfOtherChild extends OtherChild {} 

myfunction(new ArrayList<OtherChild>(), new Factory<ChildOfOtherChild>() { 
    @Override public ChildOfOtherChild create() { return new ChildOfOtherChild(); } 
    }); 
} 
+0

那好多了,但是如何創建T型元素? – 2011-04-23 12:01:56

+0

這不能在Java中工作。你不能做'new T()',其中T是一個類型參數。你可以用工廠來解決這個問題(我正在寫一個討論這個問題的答案的附錄) – 2011-04-23 12:07:28

+0

+ 1用於解釋工廠機制! – 2011-04-23 13:00:48

5

什麼List<? extends Parent>手段是簡單的答案可能會產生「僅包含Parent某些未知子類的實例的列表」 - 並且由於您不知道子類是什麼子類,因此除列表null之外不能添加任何內容(但可以從中獲得Parent實例)。

如果你要的實例添加到列表中的特定子類Child,那麼你真正需要的是這樣的:

public List<Child> myfunction(List<Child> mylist) 
+1

「不能添加任何東西」並不完全正確。你*可以*添加'null'。 – 2011-04-23 13:25:06

-2

有關添加return陳述或聲明的方法返回什麼void ...

+0

這個例子只是爲了解釋的目的而寫的,因爲你可以看到我用父母和孩子的比喻隨意編輯 – 2011-04-23 11:50:00

+0

是的,這也是這裏的問題。 – Boro 2011-04-23 11:50:21

+0

你在這裏說什麼? – 2017-03-14 06:36:46

1

other question繼喬恩斯基特的例子,假設你使用

public List<? extends Fruit> myfunction(List<? extends Fruit> mylist){ 
     mylist.add(new Apple()) ; //Doesn't Compile 
     return myList; 
} 

但後來被稱爲它與

List<Banana> bananas = new ArrayList<Banana>(); 
bananas = myfunction(bananas); 

您不能將一個蘋果添加到香蕉列表中。

可以做的是什麼

public List<Fruit> addApple(List<Fruit> mylist){ 
     mylist.add(new Apple()) ; 
     return myList; 
} 

public List<Fruit> addBanana(List<Fruit> mylist){ 
     mylist.add(new Banana()) ; 
     return myList; 
} 
相關問題