我想知道为什么下面的代码不起作用:
Collection <? super String> col = new ArrayList<String>();
col.add(new Object());// does not compile
col.add("yo!");// compiles indeed;
如果类型为<? super String>
,它可以包含超出String
(包括字符串)的任何内容吗?
答案 0 :(得分:15)
Collection<? super String>
,与你的直觉相反,并不意味着“包含String
类型的对象或其超类型的集合”。这意味着“col
将是一个包含某些明确类型的集合,其本身为String
或其超类型”(例如Object
,Serializable
或CharSequence
)。
考虑Collection<? super String>
的最佳方式是,它不是像Java中习惯的那样的类型,而是与特定类型匹配的模式。
现在,您可以安全地添加到与上述模式匹配的任何集合中的唯一事情是String
或其子类(如果有的话)。与你的期望完全相反,不是吗?这是你的泛型。
答案 1 :(得分:3)
使用Collection <? super String>
,我们无法确切知道它包含哪种对象,但我们知道它必须是String
或{{1}的某些超类的集合},即将String
放入<{1}}是安全的,但不一定是String
。相反,对于从集合中取出事物的方法(例如,在迭代时),我们无法确定我们会收回字符串。
另一方面,对于Object
,我们知道它是Collection<? extends Foo>
或Foo
的某个子类的集合,因此我们可以安全取< / em>集合中的某些内容并知道它可以分配给Foo
,但我们无法将任何内容放入其中,因为我们无法知道哪些类型是安全的。