我有关于泛型的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)
有什么想法吗?
答案 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;
}
似乎参数化需要你使用?在列表中签名以接收结果,然后将列表转换为预期的返回类型。
我仍然对仿制药感到眼花缭乱...