【问题标题】:Generics <? super> wildcard泛型 <?超级>通配符
【发布时间】:2013-07-02 07:56:48
【问题描述】:

我想知道为什么以下代码不起作用:

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

如果类型是&lt;? super String&gt;,它可以包含String 的超级元素(包括字符串)不是吗?

【问题讨论】:

  • &lt;? super String&gt; 只能添加字符串。 Object 不能是字符串。尝试这样做:Object myObj = new String();,它应该可以工作。
  • 不,任何扩展字符串。这意味着?其超级是字符串.
  • @m0skit0 这就是我感到困惑的地方。谢谢。
  • @m0skit0 Ops.. 为什么如果我再尝试做&lt;? super String&gt; col = new ArrayList&lt;Object&gt;(); 它编译!但是对象不扩展字符串!这些泛型..
  • 对不起,我的错,请参阅 Marko 的回答。

标签: java generics collections


【解决方案1】:

Collection&lt;? super String&gt;,与您的直觉相反,并不意味着“包含String 或其超类型对象的集合”。这意味着“col 将是一个包含某种确定类型的集合,它本身是String 或其超类型”(例如ObjectSerializableCharSequence)。

考虑Collection&lt;? super String&gt; 的最佳方式是它不是一个类型,就像您在Java 中习惯的那样,而是一个匹配特定类型的模式

现在,您唯一可以安全地添加到与上述模式匹配的任何集合中的是String 或其子类(如果有的话)。与您的预期完全相反,不是吗?这就是你的泛型。

【讨论】:

  • 嘿,不错。为了完成您的示例,可以将 String 放入 Collection&lt;? super CharSequence&gt;...
  • 感谢Marko的清晰解释,你的回答对我有帮助已经不是第一次了
【解决方案2】:

对于Collection &lt;? super String&gt;,我们不知道它究竟包含什么类型的对象,但我们知道它必须是StringString 的某个超类的集合,也就是说,放一个String,但不一定是Object。相反,对于从集合中取出东西的方法(例如,在迭代时),我们不能确定是否会取回字符串。

另一方面,对于 Collection&lt;? extends Foo&gt;,我们知道它是 FooFoo 的某个子类的集合,因此我们可以安全地获取集合中的某些内容并知道它可以分配给Foo,但我们不能放入任何东西,因为我们无法知道哪些类型是安全的。

【讨论】:

  • 很好的解释,我现在明白了~
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-30
  • 1970-01-01
  • 2013-04-02
  • 2023-03-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多