ArrayList泛型:子类

时间:2015-12-10 14:28:25

标签: java generics arraylist

为什么语句1有效,即使语句2无效。我能理解陈述2无效的原因,但为什么同样的原则不适用于Statament 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;
    }
}

2 个答案:

答案 0 :(得分: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 ObjectA任何意味着你可以拥有任何扩展ObjectA(如果它是一个类)或在RHS上实现ObjectA(如果它是一个接口)的对象。

答案 1 :(得分:0)

这是因为泛型不是在Java中实现的,它们在编译时被删除。声明1无效,但在较宽松的情况下转换为ArrayList。声明2具有强类型,其关系为“所有ObjectB s为ObjectA s,但并非所有ObjectA都为ObjectB s”。这类似于“并非所有动物都是狗,但所有的狗都是动物。”