我在Java中有泛型类的问题。
我有这节课:
public abstract class MyMotherClass<C extends AbstractItem>
{
private C item;
public void setItem(C item)
{
this.item = item;
}
public C getItem()
{
return item;
}
}
此类的实现可以是:
public class MyChildClass extends MyMotherClass<ConcreteItem>
{
}
ConcreteItem只是扩展AbstractItem(抽象)的简单类。
所以MyChildClass具有ConcreteItem,我可以使用:
MyChildClass child = new MyChildClass();
child.setItem(new ConcreteItem());
// automatic cast due to generic class
ConcreteItem item = child.getItem();
好吧,目前一切都很好。这是问题所在:
现在,我想从一个集合中提取MyMotherClass的实例并设置其项目(类型未知):
Map<String, MyMotherClass> myCollection = new HashMap<String, MyMotherClass>();
Map<String, AbstractItem> myItems = new HashMap<String, AbstractItem>();
// fill the 2 collections
...
MyMotherClass child = myCollection.get("key");
child.setItem(myItems.get("key2"));
如果我这样做,它将运行。
但是我有警告,因为MyMotherClass是泛型类型,并且我不使用泛型类型。
但是我不知道提取的孩子是哪种类型,因此我想使用通配符:
Map<String, MyMotherClass<?>> myCollection = new HashMap<String, MyMotherClass<?>>();
Map<String, AbstractItem> myItems = new HashMap<String, AbstractItem>();
// fill the 2 collections
...
MyMotherClass<?> child = myCollection.get("key");
child.setItem(myItems.get("key2"));
这是问题所在:我遇到了编译错误,内容为:
类型MyMotherClass的方法setItem(capture#1-of?)不适用于自变量(AbstractItem)
当我尝试继承的通配符时,同样的问题:
Map<String, MyMotherClass<? extends AbstractItem>> myCollection = new HashMap<String, MyMotherClass<? extends AbstractItem>>();
Map<String, AbstractItem> myItems = new HashMap<String, AbstractItem>();
// fill the 2 collections
...
MyMotherClass<? extends AbstractItem> child = myCollection.get("key");
child.setItem(myItems.get("key2"));
我能做什么 ?
感谢和抱歉我的英语不太流利;)
最佳答案
我可能会丢失一些内容,但是为什么不使用显式类AbstractItem
而不是通用类C
在MyMotherClass类中添加以下内容?
public abstract class MyMotherClass<C extends AbstractItem> {
private AbstractItem item;
public void setItem(AbstractItem item) {
this.item = item;
}
public AbstractItem getItem() {
return this.item;
}
}
仅此更改便可以让您使用通配符方法:
Map<String, MyMotherClass<?>> myCollection = new HashMap<String, MyMotherClass<?>>();
Map<String, AbstractItem> myItems = new HashMap<String, AbstractItem>();
// fill the 2 collections
MyMotherClass<?> child = myCollection.get("key");
child.setItem(myItems.get("key2"));
没有错误。
当然,在
MyChildClass
中,您可以按以下方式覆盖MyMotherClass#getItem()
:@Override
public ConcreteItem getItem() {
return (ConcreteItem) super.getItem();
}
确保返回正确的课程;对
MyMotherClass
的所有子类使用相同的方法,将允许您返回正确的类型。