名单<! - ?扩展MyType - >

时间:2009-05-27 21:10:08

标签: java list generics bounded-wildcard

我有关于泛型的Java问题。我宣布了一个通用名单:

List<? extends MyType> listOfMyType;

然后在某些方法中,我尝试实例化并将项添加到该列表中:

listOfMyType = new ArrayList<MyType>();
listOfMyType.add(myTypeInstance); 

myTypeInstance只是MyType类型的对象;它不会编译。它说:

  

方法添加(捕获#3-of?extends   MyType)类型为List&lt; capture#3-of   ?扩展MyType&gt;不适用   对于参数(MyType)

有什么想法吗?

5 个答案:

答案 0 :(得分:29)

你不能用扩展名做“put”。请看Generics - Get and Put rule

答案 1 :(得分:25)

考虑:

class MySubType extends MyType {
}

List<MySubType> subtypeList = new ArrayList<MySubType>();
List<? extends MyType> list = subtypeList;
list.add(new MyType());
MySubType sub = subtypeList.get(0);

sub现在包含一个非常错误的MyType

答案 2 :(得分:4)

在您的情况下,您不需要使用通配符捕获语法,只需声明

即可
List<MyType> listOfMytype;

应该足够了。如果你想确切地知道为什么,Java Generics Tutorial比你想知道的Java Generics的深奥疯狂更多。第20页解决了您的具体情况。

至于为什么使用通配符捕获添加不起作用,这是因为编译器无法准确确定列表在每种情况下的MyType子类,因此编译器会发出错误。

答案 3 :(得分:3)

这里有一个类似的主题: How can elements be added to a wildcard generic collection?

要了解泛型如何工作,请查看此示例:

    List<SubFoo> sfoo = new ArrayList<SubFoo>();
    List<Foo> foo;
    List<? extends Foo> tmp;

    tmp = sfoo;
    foo = (List<Foo>) tmp;

问题是,这不是为本地/成员变量而设计的,但对于功能签名而言,这就是为什么它如此向后倾斜。

答案 4 :(得分:2)

我不知道这是否真的会对你有所帮助,但这是我在调用Spring Framework的泛型方法时必须使用的东西,并希望返回一个通用列表:

public <T> List<T> findAll(String tableName,Class<?> table) {
    String sql = "SELECT * FROM "+ tableName ;
    List<?> entities = getSimpleJdbcTemplate().query(sql,
            ParameterizedBeanPropertyRowMapper.newInstance(table));
            return (List<T>) entities;
}

似乎参数化需要你使用?在列表中签名以接收结果,然后将列表转换为预期的返回类型。

我仍然对仿制药感到眼花缭乱...