【问题标题】:ArrayList Generics: subclassArrayList 泛型:子类
【发布时间】:2015-12-10 14:28:25
【问题描述】:

为什么声明 1 有效,即使声明 2 无效。声明2无效的原因我可以理解,但为什么相同的原则不适用于声明1?

import java.util.*;

public class CollectionTest
{
    public static void main(String[] args)
    {
        ArrayList<ObjectB> test = new ArrayList<ObjectA>(); //statement 1

        ObjectB B = new ObjectA("aaa");//statement 2
    }
}

class ObjectA
{
    String a;
    ObjectA(String str) { 
        a = str;
    }
}

class ObjectB extends ObjectA
{
    String b;
    ObjectB(String str) {
        super(str);
        b = str;
    }
}

【问题讨论】:

  • 您正在比较两个(无效)不同的东西。如果你想做类比,你应该这样定义你的数组列表:ArrayList&lt;ObjectB&gt; test = new ArrayList&lt;ObjectB&gt;();

标签: java generics arraylist


【解决方案1】:

两者都是无效的。如果你尝试运行它,你会得到编译器错误。您不能将子类引用分配给超类对象。您只能将超类引用分配给子类对象,例如ObjectA a = new ObjectB();此外,当涉及到泛型时,规则更加严格。您在左侧传递的类型应与右侧的类型匹配,如下所示。

ArrayList<ObjectB> test1 = new ArrayList<ObjectB>(); // valid

(或)

ArrayList<ObjectA> test2 = new ArrayList<ObjectA>();  // valid

如果您尝试将之前的超类引用规则应用于子类对象,则会在泛型的情况下抛出错误。

ArrayList<ObjectA> test = new ArrayList<ObjectB>(); // error

如果你真的想要一个子类对象列表来引用超类,你可以使用extends关键字来做到这一点。

ArrayList<? extends ObjectA> test = new ArrayList<ObjectB>(); // valid
ArrayList<? extends ObjectA> test = new ArrayList<ObjectA>(); // valid

? extends ObjectAanything 意味着您可以在 RHS 上拥有扩展 ObjectA(如果它是一个类)或实现 ObjectA(如果它是一个接口)的任何对象。

【讨论】:

    【解决方案2】:

    这是因为泛型在 Java 中没有具体化,它们在编译时被删除。声明 1 无效,但在更宽松的情况下转换为 ArrayList。语句 2 具有强类型,其关系为“所有 ObjectBs 都是 ObjectAs 但并非所有 ObjectAs 都是 ObjectBs”。这类似于“并非所有动物都是狗,但所有狗都是动物”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-06
      • 2014-06-12
      • 1970-01-01
      • 2021-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-02
      相关资源
      最近更新 更多