为什么我在这段代码上出现编译时错误?
public Interface Location {
.......
}
班级代码......
Map<Type, List<? extends Location>> locationsTypeMap = new HashMap<Type, List<? extends Location>>();
/**
Code to add elements to the hashMap.
*/
newLocation = getNewLocation()
while(mapHasElements){
Location.Type key = location.getType();
List<? extends Location> valueList = (List<? extends Location>)locationsTypeMap.get(key); //1
valueList.add(newLocation);/*Compile error*/
}
另一方面,如果我将步骤1替换为下面的行,则可以使用
List<Location> valueList = (List<Location>)locationsTypeMap.get(key);
答案 0 :(得分:11)
通配符“?extends Location”表示“我希望List<T>
为某些T
T
是Location
的子类(或{{1}本身)。“
现在,让我们把它留到一边一秒钟。你期望这个编译:
Location
?我不这么认为 - 你不能将一个简单的“对象”添加到字符串列表中。字符串列表中的任何项都必须是字符串。
回到你的第一件事。假设List<String> strings = new List<String>();
strings.add(new Object());
返回一个对象(逻辑上 - 暂时忽略类型擦除)a locationsTypeMap.get(key)
- 但假设newLocation实际上是List<ExoticLocation>
的一个实例。您不应该将BoringLocation
添加到BoringLocation
并且编译器知道 - 所以它会阻止它发生。
来自 List<ExoticLocation>
的任何内容都保证是某种List<? extends Location>
...但您无法添加任何内容。 Location
反之亦然:您不能保证从super
获得的任何内容都是List<? super Location>
,但您可以添加Location
1}}到它。
举一个非常不同的例子:是一堆香蕉是水果的集合吗?嗯,从某种意义上说 - 你从中得到的任何东西都是的果实。但它不在另一个,因为你不能添加任何旧的水果 - 如果你试图添加一个苹果,它会脱落:)
有关详情,请参阅Angelika Langer's Java Generics FAQ。
答案 1 :(得分:-1)
它是一个可以为空的类型:
http://msdn.microsoft.com/en-us/library/1t3y8s4s%28VS.80%29.aspx
编辑:鉴于上述两个答案,我一定是错的!遗憾!