我在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的所有子类使用相同的方法,将允许您返回正确的类型。

09-11 18:30