繁体   English   中英

Java Arrays与Generics

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM