【问题标题】:Generics extends and super with ? differencies泛型扩展和超级 ?差异
【发布时间】:2014-03-08 13:06:21
【问题描述】:

我尝试理解 java 中的泛型行为

我写了同样的代码:

共同部分:

class A1{}
class B1 extends A1{}
class C1 extends B1{}

案例一:

        List<? extends B1> list = new ArrayList<C1>();
        list.add(new A1());// compile error
        list.add(new B1());//compile error
        list.add(new C1());//compile error

案例2:

        List<? super B1> list = new ArrayList<A1>();
        list.add(new A1());//compile error
        list.add(new B1());//valid
        list.add(new C1());//valid

我认为我编写了简单的代码。为什么我看到非对称结果?

【问题讨论】:

  • 其中哪些结果让您感到惊讶,为什么?
  • 我认为 super 和 extends 是对称的
  • 你明白它们的意思吗?如果没有,你为什么不问呢?如果你这样做了,那么你会惊讶于什么结果?
  • @JB Nizet 列表 extends B1> list - 我不能通过这个引用添加任何东西,但是当我使用 List列表
  • 在我遇到这段代码后,我明白我对泛型的理解有误

标签: java generics inheritance wildcard


【解决方案1】:

List&lt;? extends B1&gt; 表示:未知类型的列表,它是或扩展 B1。所以它可能是List&lt;B1&gt;List&lt;C1&gt;List&lt;Foo&gt;,如果Foo 也扩展了B1C1。所以你不能在这样的列表中添加任何东西:

list.add(new A1); // incorrect, since A1 doesn't even extend B1
list.add(new B1()); // incorrect, since the list could be a List<C1>
list.add(new C1()); // incorrect, since the list could be a List<Foo>

您可以添加到此类列表中的唯一内容是 null。

List&lt;? super B1&gt; 表示:未知类型的列表,它是 B1 或B1 的超类或超接口。所以它可能是List&lt;B1&gt;List&lt;A1&gt;List&lt;Object&gt;(仅此而已)。所以

list.add(new A1()); // incorrect, since the list could be a List<B1>, and A1 is not a B1
list.add(new B1()); // valid, since whatever the type of the list (B1, A1 or Object), B1 is of this type
list.add(new C1()); // valid, since whatever the type of the list (B1, A1 or Object), B1 is of this type

但是,如果您尝试从此类列表中获取元素,则无法保证其类型。唯一确定的是它是一个对象。

总的原则是PECS:Producer Extends,Consumer Super。这意味着当列表是生产者时(这意味着您想从中获取元素),那么应该使用extends。当列表是消费者时(这意味着您要向其添加元素),则应使用super

【讨论】:

  • 这个答案真的很有帮助
  • Nizet 我认为如果你的意思是 > 在你的优秀答案中会很好
  • 如果你不能添加任何东西,什么时候有人使用&lt;? extends X&gt;
  • 但现在我想到了最后的课程
  • 那么什么时候有人使用:当您设计一个将 List 作为参数并且只能从列表中读取元素的方法时。例如:Collections.binarySearch()。关于扩展和超级,最终类与非最终类没有什么不同。
猜你喜欢
  • 2012-10-19
  • 2012-09-18
  • 1970-01-01
  • 2012-08-30
  • 1970-01-01
  • 2018-11-20
  • 2010-12-27
  • 2016-10-21
  • 1970-01-01
相关资源
最近更新 更多