2015-12-10 131 views
-3

为什么即使语句2无效,语句1仍然有效。我可以理解声明2无效的原因,但为什么同样的原则不适用于声明1?ArrayList泛型:子类

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; 
    } 
} 
+0

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

+4

两者都是无效的。 –

回答

0

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

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(如果它是一个接口)。