类型List中的方法add(capture#2-of?extends IObject)不适用于参数(IDerived)
protected List<? extends IObject> getObjects()
{
List<? extends IObject> objects = new ArrayList<IObject>();
for (String id: item_ids)
{
IDerived object = (IDerived) readObject(id);
objects.add(object); #error
}
return objects;
}
interface IDerived extends interface IVersionedObject extends interface IObject
如果我将对象的类型更改为List,那么错误就会消失,这没有任何意义,因为它必须对函数返回类型进行完全相同的转换。
答案 0 :(得分:7)
试试这个:
protected <T extends IObject> List<T> getObjects() {
List<T> objects = new ArrayList<T>();
for (String id: item_ids)
{
T object = (T) readObject(id);
objects.add(object); // NO error
}
return objects;
}
编辑(简短说明):
这样你的方法可以适用于IObject的任何子类型(里面的列表和强制转换都是通用的),返回类型将从调用者的期望中推断出来(正如你明显的意图)。
在回复注释时,您现在可以通过以下方式调用getObjects()方法:
// This should only be used if readObject() behaves like
// getObjects() and is able to return any requested subtype.
// Otherwise, you'll get a ClassCastException when trying to get
// something from the derivedList in case readObject() put something
// else there (which is not a subtype of IDerived).
List<IDerived> derivedList = getObjects();
// This is the safe way to go in case you don't have
// full control over what readObject() returns.
// But if you're using it like this (all the time), you'd better
// return List<IObject> from getObjects() and get rid
// of generics.
List<? extends IObject> objectList1 = getObjects();
List<IObject> objectList2 = getObjects();
答案 1 :(得分:4)
我不知道我是否会解释这个问题,但我会去。
List<? extends IObject> objects = new ArrayList<IObject>();
说该列表是一个扩展IObject的未知类型。即使您在rhs上放置new ArrayList<IObject>();
,列表泛型类型仍未严格定义。换句话说,当您为其分配引用时,泛型类型不会被“烘焙”。
因此,当您致电objects.add(object);
时,类型检查程序不知道该列表将与IDerived兼容,因为该列表可能是IVersionedObjectSomethingElse
类型。即使你从逻辑流程中发现这是不可能的,也可以构建。
List<? extends IObject> objects = null;
if (test) {
objects = new ArrayList<IObject>();
}
else {
objects = new ArrayList<IVersionedObject2>();
}
objects.add( (IDerived) iDerivedObj ); // iDerived *might* not be compatible
答案 2 :(得分:0)
为什么要使用通配符?而不是? extends IObject
,请使用IDerived
更改此行
List<? extends IObject> objects = new ArrayList<IObject>();
到此:
List<IDerived> objects = new ArrayList<IDerived>();
并改变
protected List<? extends IObject> getObjects()
到
protected List<IDerived> getObjects()