简体   繁体   English

泛型<?超级>通配符

[英]Generics <? super> wildcard

I was wondering why the following bit of code does not work: 我想知道为什么下面的代码不起作用:

Collection <? super String> col = new ArrayList<String>();
col.add(new Object());// does not compile
col.add("yo!");// compiles indeed;

If the type is <? super String> 如果类型是<? super String> <? super String> it can contain anything which is super of String (String included) not? <? super String>它可以包含任何超级String (包括字符串)不是吗?

Collection<? super String> Collection<? super String> , counter to your intuition, does not mean "a collection which contains objects of type String or its supertype". Collection<? super String> ,与你的直觉相反, 并不意味着 “包含String类型的对象或其超类型的集合”。 It means " col will be a collection holding some definite type, which itself is String or its supertype" (such as Object , Serializable , or CharSequence ). 这意味着“ col将是一个包含某些确定类型的集合,它本身就是String或其超类型”(例如ObjectSerializableCharSequence )。

The best way to think about Collection<? super String> 考虑Collection<? super String>的最佳方式Collection<? super String> Collection<? super String> is that it is not a type, like you are used to in Java, but a pattern against which specific types are matched. Collection<? super String>是,它是不是一个类型的,就像你是用来在Java中,而是一个模式针对其特定类型的匹配。

Now, the only thing you can safely add to any collection which matches the above pattern is a String or its subclass (if there were any). 现在,您可以安全地添加到与上述模式匹配的任何集合中的唯一事情是String或其子类(如果有的话)。 Quite the opposite of what you would have expected, isn't it? 与你的期望完全相反,不是吗? That's Generics for you. 那是你的泛型。

With a Collection <? super String> Collection <? super String> Collection <? super String> , we don't know what kind of objects it contains exactly, but we know that it must be a collection of either String or some superclass of String , ie it is safe to put a String into it but not necessarily an Object . Collection <? super String> ,我们不知道它究竟含有什么样的对象,但我们知道,它必须是集合String或者一些超String ,也就是说,它是安全的一个String到它,但不一定是一个Object Conversely for methods that take things out of the collection (eg when iterating) we can't be sure we'll get strings back. 相反,对于事物从集合中取出的方法(例如,在迭代时),我们无法确定我们是否会收回字符串。

On the other hand with Collection<? extends Foo> 另一方面, Collection<? extends Foo> Collection<? extends Foo> we know it's a collection of something that is either Foo or some subclass of Foo , so we can safely take something from the collection and know it will be assignable to Foo , but we can't put anything in because we have no way of knowing what types would be safe. Collection<? extends Foo>我们知道这是的东西,或者是一个集Foo或某些子类Foo ,所以我们可以安全地从收集的东西,知道这将是分配给Foo ,但我们不能任何东西,因为我们没有知道什么类型是安全的方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM