为什么语句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;
}
}
答案 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”。这类似于“并非所有动物都是狗,但所有的狗都是动物。”