2014-07-11 43 views
3

为:泛型方法不能正确识别类型

Map<Class<? extends Model>, List<? extends Model>> mockStore; 

在这个类中我有一个方法:

protected <T extends Model> void insertMockStore(T obj) 
{ 
    mockStore.get(obj.getClass()).add(obj); 
} 

但这种方法给出一个编译错误:

的方法Add(捕获#8的?延伸模型)在类型为List是不适用的参数(T)

我不明白这个错误,因为T被定义为扩展模型,所以为什么会说T不适用?

回答

6

你的成员声明说的mockStore值将是包含的Model未指定的子类*名单。

insertMockStore方法做类似,但没有什么保证Model的子类传递给insertMockStore将与列表相同。

你应该做的,而不是为声明mockStore这样的:

Map<Class<? extends Model>, List<Model>> mockStore; 

一个容易记住的经验法则这里是“佩奇规则”:生产者延伸,消费超。这意味着如果您的会员拥有类型参数为Foo的集合,则所有生产者类型方法(插入到您的集合中的那些方法)将需要T extends Foo,并且所有消费者类型方法(从集合中返回值的方法)都应该有T super Foo。 *与泛型一样,在“子类”中,我们包括类本身。

+3

我知道这会让我错过一些简单的事情。感谢您的输入! –

1

您的mockStore具有List<? extends Model>值,因此它不知道您是否可以向其添加T

更简单的解决方案是简化您的声明。

private final Map<Class, List> mockStore; 

@SuppressWarning("unchecked") 
protected void insertMockStore(Model obj) { 
    mockStore.get(obj.getClass()).add(obj); 
} 
+1

但我认为OP需要它们通用的 – GingerHead

+0

@GingerHead没有在给出的例子中。通常在这些情况下,元素类型匹配最终使用擦除的密钥,并在方法中强制执行。 –