Java泛型:将元素添加到Set <!-?->,Set <!-?扩展Integer->和Set <!-?超级整数->

时间:2018-06-21 09:49:26

标签: java

因此,我正在修改一些Java概念,发现在最“复杂”的情况下我并不完全理解泛型。我大约有3个月的Java课和一个考试,所以我将不胜感激!

在所附示例中,我不明白为什么1)和2)无效。

谢谢!

enter image description here

1 个答案:

答案 0 :(得分:2)

您可以很轻松地考虑这一点。 List<? extends SomeClass>始终产生SomeClass的实现。请参见以下示例:

List<Integer> ints = new Arrays.asList(1,2,3,4);
List<? extends Number> nums = ints; // this does work
Integer i = nums.get(0); // this doesn't
Number num = nums.get(0); // this does again
nums.add(5); // this doesn't too

您看到nums拥有对ints的引用。因为Integer扩展了Number。而且,如果您阅读nums列表,总会得到Number

这对于每个超类-子类关系都适用。

但是:您无法写入nums列表。也就是说,由于您不完全确切地知道nums实际引用了哪个列表,在上面的示例中,它是Integer个列表,因此您只知道会发生什么阅读时从列表中选择。


List<? super SomeClass>相同,这与上述内容相反。它将始终使用任何SomeClass的实现。再次查看示例:

List<Object> objs = new ArrayList<>();
List<? super String> strings = objs; // this does work
strings.add("Some String"); // this works
String string = strings.get(0); // this doesn't
Object object = strings.get(0); // this does again

现在我们只知道类型String和更具体的每个元素都可以放入Strings列表中。因为这是上面的反面。如果您尝试阅读列表,则不知道会得到什么。您只能阅读Object,但永远不会知道它们的实际类别。


通常称为PECS,代表:生产者extends消费者super。有关该主题的更多信息,请参见this question