【问题标题】:super and extends behaves same way [duplicate]super 和 extends 行为相同[重复]
【发布时间】:2014-12-21 23:27:21
【问题描述】:

这个问题以前可能以不同的形式被问过,但我找不到合适的答案。

这些代码有什么区别:

第一密码

ArrayList<? super Number> list=new ArrayList<>(Arrays.asList(1));

第二个密码

ArrayList<? extends Number> list=new ArrayList<>(Arrays.asList(1));

两个语句都编译。请说明为什么前者编译。它也显示了 Integer extends Number 和 Integer super Number。

编辑::

我期待的答案是: new ArrayList(Collection&lt;? extends E&gt;) 因此它们都编译了。

这样,这不是重复的问题,因为引用的答案没有描述。

【问题讨论】:

  • 据我所见,您已将完全相同的代码行 c/p'ed 到您的问题中?

标签: java oop generics collections


【解决方案1】:

它们都以相同的方式执行,但编译器会阻止它们以不同的方式编译。

public class NewClass {

    private List<? super Number> supers;

    private List<? extends Number> extenders;

    public NewClass() {
        supers = new ArrayList<>();
        extenders = new ArrayList<>();
    }

    public void addSupers() {
        supers.add(new Integer("5"));
    }

    public void addExtenders() {
        // This won't compile
        extenders.add(new Integer("5"));
    }

    public void getSupers() {
        // this won't compile
        Number number = supers.get(1);
    }

    public void getExtenders() {
        Number number = extenders.get(1);
    }

}

在supers 添加案例中,您可以安全地添加Integers,因为Integers 有一个超类Number。在extenders 的情况下您不能这样做,因为扩展程序持有Number 的特定子类,在这种情况下,它由通配符确定。简而言之,通常假定extenders 项包含所有相同的 Number 子类。

在supers 获取案例中,您不能安全地取出Number,因为对于某些类型,可能不是Numbers,而是Number 的超类,因此“向下转换”是危险的。但是,在extenders 场景中,所有内容都被保证是Number 的子类,因此它们都可以安全地转换为Number。

【讨论】:

  • @user2653926 正在研究中。想要提供代码来备份它,而不仅仅是英语。
【解决方案2】:

&lt;? super Number&gt; 表示该类型是Number 的任何超类。

&lt;? extends Number&gt; 表示该类型是Number 的任何子类。

它们将编译成相同的东西,但这取决于您实际上要使用 List 做什么类型。

如果您有List&lt;? super Number&gt;,您可以将任何Number 放入其中,但编译器不能保证您从中得到的将是Number。而如果你有一个List&lt;? extends Number&gt;,那么你得到的任何东西肯定会继承自Number。

如果尝试将List&lt;? super Number&gt; 传递给期望List&lt;? extends Number&gt; 的方法,编译器将反对,因为前者可能包含不是Number 的内容。

如果尝试将List&lt;? extends Number&gt; 传递给期望List&lt;? super Number&gt; 的方法,编译器将反对,因为前者不一定能接收后者可以接收的元素。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-11
    • 1970-01-01
    • 2012-05-07
    • 2021-11-23
    • 2020-08-14
    • 1970-01-01
    相关资源
    最近更新 更多