2016-06-18 53 views
1

我試圖創建一個將定義列表中的元素添加到泛型列表中的方法。Java泛型 - 如何將非泛型添加到通用列表

下面是代碼:上types.add(v);與錯誤消息(T) in List cannot be applied to (com.test.entities.IEntity)發生

private List<IEntity> entities = new ArrayList<IEntity>(); 

public <T extends IEntity> List<T> values(Class<T> type) { 
    List<T> types = new ArrayList<T>(); 

    for (IEntity v : entities) { 
     types.add(v); //Error 
    } 

    return types; 
} 

的語法時才錯誤。

有沒有什麼辦法可以做到我想要的效率而不必施放?

回答

9

編譯器給你一個類型錯誤,因爲你的程序不安全。

您有List<T>。你不知道T是什麼,只是它延伸IEntity。 (讓我們使用Number作爲示例,而不是IEntity,以使其更清晰。)因此,您有一個列表中的某種數字,也許它是一個List<Integer>,或者可能是一個List<Float>,您不知道。你正在試圖向它添加一個數字。但是你沒有理由相信這個列表可以容納數字! A List<Integer>不能容納任意數字,因爲您不能將Long或Float或Short放入List<Integer> - Java泛型是不變的。

因此,基本上你的程序被破壞,編譯器告訴你。

0

您不能將IEntity插入保存子類IEntity - T extends IEntity的列表中。你需要一個列表,其中包含IEntity的超類,以便將IEntity放入其中 - T super IEntity

0

由於您沒有提供有關您要執行的具體結構的更多信息,因此很難提供更好的解決方案。

interface Entity {} // In Java, unlike in .NET environment, interface names do not begin with "I". You write Entity or EntityInterface, sometimes also EntityInt 

class EntityImpl { 
    private final List<Entity> entities = new ArrayList<>(); 

    // List of T is undefined 
    public <T extends Entity> List<T> getValues(Class<T> type) { // in Java it's important to write "get" for a getter-method before the property-name, if it's not a boolean-getter. 
     List<T> types = new ArrayList<>(); 
     types.addAll((Collection<? extends T>) entities); 
     return types; 
    } 
} 
0

如果你想做一個泛型類,你可以做這樣的事情。

private class MyClass<T extends IEntity> { 
    private List<T> entities; 

    ... 

    public List<T> values() { 
     List<T> types = new ArrayList<>(); 

     for (T v : entities) { 
      types.add(v); // All Good 
     } 
     return types; 
    } 
} 

interface IEntity { ... } 

interface ISubEntity extends {...} 

然後,當你知道你正在使用ISubEntity,您可以實例如下:

MyClass<ISubEntity> myClass = new MyClass<>(); 

隨後對值的調用將返回爲您鍵入的列表。

這裏是關於泛型的在線正式doc