java中的cast arraylist和cast数组之间的差异

时间:2014-06-27 07:46:20

标签: java arrays arraylist casting

正如Jon post的回答所说,如果编译器允许这个演员(如下所示),以后添加一些其他对象对程序来说可能是件坏事。

    ArrayList<String> temList = new ArrayList<String>();
    ArrayList<Object> obList = (ArrayList<Object>)temList;//compile error
    //obList.add(1); --bad

但令我困惑的是,为什么在同样的情况下,数组会有不同的行为。

    String[] strings = new String[10];
    Object[] temp = (Object[])strings;//nothing happens

那么有人可以解释这里的差异以及为什么java会做出如此设计的原因?感谢。

修改:一个类似的question

2 个答案:

答案 0 :(得分:1)

数组不是100%的对象,它们是平凡的对象。但ArrayList是一个100%的对象。

如果您尝试将一个Integer分配给临时数组,它将抛出一个ArrayStoreException

所以投射阵列很好。

但是将ArrayList转换为超级对象,其中底层ArrayList实现只能包含String(子类)将在运行时期间导致问题。

感谢Generics,编译器可以在它发生之前识别它并且可以显示编译器错误。如果程序在运行期间失败,这是一个很好的设计。

Java 1.5 Generics之前

List list = new ArrayList();
list.add(1);
list.add("One");
list.add(100l);

合法人员必须进行大量instanceof检查。他们未能检查程序在运行时崩溃的地方。

答案 1 :(得分:0)

如果数组的组件类型可分配给指定数组的组件类型,则设计数组以允许协变分配。类型检查在运行时由JVM完成,其中如果尝试将值存储在不兼容的数组中,则抛出ArrayStoreException。使用正确,这允许表达数组的协变类型,这通常很方便。

但是,这种语言特性可能导致漫反射运行时异常,Sun不希望重复这些异常,因为Java 5引入了泛型类型赋值。相反,Sun希望在编译时发现这种无效使用。这似乎特别重要,因为泛型引入了比数组类型更复杂的类型系统组件,因此如果Sun决定采用不同的方式,类似于ArrayStoreException的运行时错误肯定会变得更加常见。相反,对于泛型,通配符解决了协方差和逆变问题,这些通配符允许在编译时而不是运行时发现类型错误。