Java通用类和通配符 [英] Java generic class and wildcards
问题描述
我在使用Java中的泛型类时遇到了问题.
I've got a problem with generic classes in 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(抽象)的简单类.
ConcreteItem is just a simple class that extends AbstractItem (which is abstract).
所以MyChildClass有一个ConcreteItem,我可以使用:
so MyChildClass have a ConcreteItem and I can use:
MyChildClass child = new MyChildClass();
child.setItem(new ConcreteItem());
// automatic cast due to generic class
ConcreteItem item = child.getItem();
好的,暂时一切都很好.问题出在这里:
Ok, all is fine for the moment. Here is the problem:
现在,我想从集合中提取MyMotherClass的实例并设置其项目(类型未知):
Now I want to extract from a collection an instance of MyMotherClass and set its item (which type is not known):
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是泛型类型,并且我不使用泛型类型.但是我不知道提取的孩子是哪种类型,所以我想使用通配符:
If I do like this, it runs. BUT I have warning because MyMotherClass is a generic type and I don't use the generic type. But I don't know which is the type of my extracted child, so I want to use a wildcard:
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)
And here is the problem: I've got a compilation error which says: The method setItem(capture#1-of ?) in the type MyMotherClass is not applicable for the arguments (AbstractItem)
当我尝试使用继承的通配符时,同样的问题:
and when I try with an inherited wildcard, same problem:
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"));
我该怎么办?
感谢和抱歉我的英语不太流利;)
thanks and sorry for my english which is not very fluent ;)
推荐答案
我可能会丢失一些东西,但是为什么不使用显式类 AbstractItem
而不是泛型在MyMotherClass类中进行以下操作类 C
?
I might be missing something, but why not do the following in your MyMotherClass class, using the explicit class AbstractItem
rather than the generic class C
?
public abstract class MyMotherClass<C extends AbstractItem> {
private AbstractItem item;
public void setItem(AbstractItem item) {
this.item = item;
}
public AbstractItem getItem() {
return this.item;
}
}
仅此一项更改就可以让您使用通配符方法:
This change alone would allow you to use your wildcard approach:
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()
:
Of course, in MyChildClass
, you can then override MyMotherClass#getItem()
as follows:
@Override
public ConcreteItem getItem() {
return (ConcreteItem) super.getItem();
}
确保返回正确的类;对 MyMotherClass
的所有子类使用相同的方法,将允许您返回正确的类型.
to make sure that the right class is being returned; this same approach for all subclasses of MyMotherClass
would allow you to return the right types.
这篇关于Java通用类和通配符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!