为我揭秘通配符
为什么这段代码会出现编译时错误?
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);
Why do I get a compile time error on this piece of code?
public Interface Location {
.......
}
Class code...
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*/
}
On the other hand, if I replace step 1 with line below it works
List<Location> valueList = (List<Location>)locationsTypeMap.get(key);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
通配符“? extends Location”表示“我希望它成为某些
T
的List
,其中T
是的子类>位置
(或者是位置
本身)。”现在,让我们把它放在一边。您希望这个编译:
?我不这么认为 - 你不能将一个裸露的“对象”添加到字符串列表中。字符串列表中的任何项目都必须是字符串。
回到你的第一件事。假设
locationsTypeMap.get(key)
返回一个对象(逻辑上 - 现在忽略类型擦除)一个List
- 但假设 newLocation 实际上是的实例代码>无聊位置。您不应该能够将
BoringLocation
添加到List
并且编译器知道这一点 - 因此它会阻止这种情况发生。您从
List 中得到什么? extends Location>
保证是某种Location
...但您不能向其中添加任何内容。super
的情况正好相反:您不能保证从List
将是一个Location
,但您可以向其中添加一个Location
。举一个非常不同的例子:一串香蕉是水果的集合吗?嗯,从某种意义上说 - 你从中得到的任何东西都是一种水果。但它不是在另一个,因为你不能添加任何旧的水果 - 如果你尝试添加一个苹果,它会掉下来:)
请参阅 Angelika Langer 的 Java 泛型常见问题解答 了解更多信息。
The wildcard "? extends Location" means "I want it to be
List<T>
for someT
whereT
is a subclass ofLocation
(or isLocation
itself)."Now, let's leave that to one side for a second. Would you expect this to compile:
? I wouldn't think so - you can't add a bare "object" to a list of strings. Any item in a list of strings has to be a string.
Go back to your first thing. Suppose
locationsTypeMap.get(key)
returns an object which is (logically - ignore type erasure for now) aList<ExoticLocation>
- but suppose newLocation is actually an instance ofBoringLocation
. You shouldn't be able to add aBoringLocation
to aList<ExoticLocation>
and the compiler knows that - so it stops that from happening.Anything you get from a
List<? extends Location>
is guaranteed to be aLocation
of some kind... but you can't add anything to it. The reverse is true withsuper
: you can't guarantee that anything you get from aList<? super Location>
will be aLocation
, but you can add aLocation
to it.To give a very different example: is a bunch of bananas a collection of fruit? Well it is in one sense - anything you get from it is a fruit. But it's not in another, because you can't add any old kind of fruit to it - if you try to add an apple, it'll fall off :)
See Angelika Langer's Java Generics FAQ for a lot more information.
它是一个可以为 null 的类型,如下所示:
http://msdn .microsoft.com/en-us/library/1t3y8s4s%28VS.80%29.aspx
编辑:鉴于上面的两个答案,我一定是错的!对不起!
Its a nullable type like so:
http://msdn.microsoft.com/en-us/library/1t3y8s4s%28VS.80%29.aspx
EDIT: I must be wrong so, given the two answers above! Sorry!