为我揭秘通配符

发布于 2024-08-16 19:49:48 字数 715 浏览 3 评论 0原文

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

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

同展鸳鸯锦 2024-08-23 19:49:48

通配符“? extends Location”表示“我希望它成为某些 TList,其中 T的子类>位置(或者是位置本身)。”

现在,让我们把它放在一边。您希望这个编译:

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

?我不这么认为 - 你不能将一个裸露的“对象”添加到字符串列表中。字符串列表中的任何项目都必须是字符串。

回到你的第一件事。假设 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 some T where T is a subclass of Location (or is Location itself)."

Now, let's leave that to one side for a second. Would you expect this to compile:

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

? 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) a List<ExoticLocation> - but suppose newLocation is actually an instance of BoringLocation. You shouldn't be able to add a BoringLocation to a List<ExoticLocation> and the compiler knows that - so it stops that from happening.

Anything you get from a List<? extends Location> is guaranteed to be a Location of some kind... but you can't add anything to it. The reverse is true with super: you can't guarantee that anything you get from a List<? super Location> will be a Location, but you can add a Location 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.

べ映画 2024-08-23 19:49:48

它是一个可以为 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!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文