为什么Java泛型的这种用法不能编译?
就我的一生而言,我无法理解为什么编译器不让我做以下事情
import java.util.HashMap;
import java.util.Map;
public class TestMap {
private final Map<Integer, ? extends Number> map = new HashMap<Integer, Number>();
public void put(Integer key, Long item) {
this.map.put(key, item);
}
}
为什么第this.map.put(key, item)
行会导致编译错误
我知道我可以将map的声明更改为使用Number
而不是? extends Number
使其工作,但在我看来,我所做的是完全合法的,我更希望不允许map中的Number对象。我正在使用Java1.6.0_13
# 1 楼答案
这与泛型协方差有关
当你申报时
例如,您不能保证
? extends Number
是一个Long
,因此无法向映射插入任何内容想象一下这种情况:
在这里,
Integer != Long
,但两者都服从? extends Number
# 2 楼答案
You can't insert into collections that use wildcard types。这是因为,虽然可以将
List<Float>
传递给接受List<? extends Number>
的方法,但在其中插入Long
是不安全的。在您的例子中,由于集合的定义是如此可见,人们可能希望编译器知道得更好,但事实并非如此# 3 楼答案
为泛型类型提供通配符可以有效地使其成为只读类型