我想知道为什么以下代码不起作用:
Collection <? super String> col = new ArrayList<String>();
col.add(new Object());// does not compile
col.add("yo!");// compiles indeed;
如果类型是<? super String>
它可以包含任何超级的String
(包括字符串)不是吗?
我想知道为什么以下代码不起作用:
Collection <? super String> col = new ArrayList<String>();
col.add(new Object());// does not compile
col.add("yo!");// compiles indeed;
如果类型是<? super String>
它可以包含任何超级的String
(包括字符串)不是吗?
Collection<? super String>
,与您的直觉相反,并不意味着“包含类型String
或其超类型对象的集合”。这意味着“col
将是一个包含某种确定类型的集合,该类型本身就是String
它的超类型”(例如Object
、Serializable
或CharSequence
)。
最好的思考方式Collection<? super String>
是,它不是一种类型,就像您在 Java 中习惯的那样,而是一种特定类型与之匹配的模式。
现在,唯一可以安全地添加到与上述模式匹配的任何集合中的是 aString
或其子类(如果有的话)。与您的预期完全相反,不是吗?那是你的泛型。
对于 a Collection <? super String>
,我们不知道它究竟包含什么类型的对象,但我们知道它必须是 的一个String
或某个超类的集合String
,也就是说,将aString
放入其中是安全的,但不一定是 a Object
。相反,对于从集合中取出东西的方法(例如,在迭代时),我们不能确定我们会得到字符串。
另一方面,Collection<? extends Foo>
我们知道它是某个东西的集合,Foo
或者是 的某个子类Foo
,所以我们可以安全地从集合中取出一些东西,并且知道它可以分配给Foo
,但是我们不能放入任何东西,因为我们没有办法知道什么类型是安全的。