5

为什么这段代码会出现编译时错误?

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);
4

2 回答 2

12

通配符“? extends Location”的意思是“我希望它在List<T>某些T地方TLocation(或Location本身)的子类”。

现在,让我们先把它放在一边。你会期望这个编译:

List<String> strings = new List<String>();
strings.add(new Object());

? 我不这么认为——你不能在字符串列表中添加一个简单的“对象”。字符串列表中的任何项目都必须是字符串。

回到你的第一件事。假设locationsTypeMap.get(key)返回一个对象(逻辑上 - 现在忽略类型擦除)List<ExoticLocation>- 但假设 newLocation 实际上是BoringLocation. 您不应该能够将 a 添加BoringLocation到 aList<ExoticLocation>并且编译器知道这一点 - 因此它阻止了这种情况的发生。

a得到的任何东西List<? extends Location>都保证是Location某种类型的......但你不能向它添加任何东西。反之亦然super:你不能保证你从 a 得到的任何东西List<? super Location>都是 a Location,但你可以添加 a Location

举一个非常不同的例子:一堆香蕉是水果的集合吗?嗯,从某种意义上说——你从中得到的任何东西都是水果。但它不在另一个,因为你不能在其中添加任何旧的水果 - 如果你尝试添加一个苹果,它会掉下来 :)

有关更多信息,请参阅Angelika Langer 的 Java 泛型常见问题解答。

于 2010-01-07T23:45:22.320 回答
-1

它是一个可以为空的类型,如下所示:

http://msdn.microsoft.com/en-us/library/1t3y8s4s%28VS.80%29.aspx

编辑:鉴于上面的两个答案,我一定是错的!对不起!

于 2010-01-07T23:48:38.050 回答