[英]Java Arrays vs Generics
假设一个SuperClass America和它的两个SubClasses SouthAmerica和NorthAmerica
情况1
对于数组:
America[] am = new SouthAmerica[10]; //why no compiler error
am[0]= new NorthAmerica(); //ArrayStoreException at RunTime
案例2
在Genrics中:
ArrayList<America> ame = new ArrayList<SouthAmerica>(); //this does not compile
我的问题不是为什么案例2不编译,但我的问题是为什么案例1编译。我的意思是还有什么可以做这个基础数组类型和子数组对象?
那是因为数组是协变的 。
数组的这种行为在很大程度上被认为是错误:
String[] strings = new String[1];
Object[] objects = strings;
objects[0] = new Integer(1); // RUN-TIME FAILURE
通用集合 - 更新,修复了这个错误。
你可以使用有界通配符表示法<? super America>
<? super America>
:
ArrayList<? super America> = new ArrayList<SouthAmerica>();
这将允许您将项添加到列表中,但它将避免有问题的行为。
请参阅此官方教程 ,了解如何使用它们。
你做错了什么。 根据您的描述,假设我们有以下内容
public class Sample {
public static void main() {
America am = new SouthAmerica[10];
}
}
class America {
private Integer Size;
}
class NorthAmerica extends America {
private Integer USA;
}
class SouthAmerica extends America {
private Integer Chile;
}
我尝试编译上面的类,它出错了。
javac Sample.java.
Sample.java:3: incompatible types
found : SouthAmerica[]
required: America
America am = new SouthAmerica[10];
1 error
案例1:我认为你的意思是:
America[] am = new SouthAmerica[10]; //why no compiler error
当SouthAmerica延伸到美国时,它对于持有一系列SouthAmerica是有效的。
第二行无效,因为该数组是SouthAmerica并且您正在尝试设置NorthAmerica。 SouthAmerica不是NorthAmerica的超类。
第一个有效的点是,以后你可以有效地说:
am=new NorthAmerica[5];
这完全归因于数组的协方差属性。
案例2:虽然SouthAmerica确实扩展了美国,但这并不适用于泛型。 由于隐含不成立,ArrayList不会扩展ArrayList。 泛型(即使在这种情况下它是一个ArrayList)也不像完整数组那样起作用。
因为数组是协变的 ,集合是逆变的 。 这意味着Stirng[]
是Object[]
,但List<String>
不是List<Object>
。 您应该写下以下内容:
List<? extends America> list = new ArrayList<SouthAmerica>();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.