java中cast arraylist和cast array之间的区别[重复]

Posted

技术标签:

【中文标题】java中cast arraylist和cast array之间的区别[重复]【英文标题】:Differences between cast arraylist and cast array in java [duplicate] 【发布时间】:2014-08-18 06:05:56 【问题描述】:

正如乔恩对此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

【问题讨论】:

@user3580294 感谢您的提醒 【参考方案1】:

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

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

【讨论】:

【参考方案2】:

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

如果您尝试将 Integer 分配给 temp 数组,它将抛出 ArrayStoreException

所以转换数组很好。

但是将ArrayList 转换为底层ArrayList 实现只能保存一个字符串(子类)的超级对象会在运行时引起问题。

感谢泛型,编译器可以在它发生之前识别它并显示编译器错误。这是一个很好的设计,否则程序会在运行时失败。

在 Java 1.5 泛型之前

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

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

【讨论】:

半无关的问题,为什么人们认为 javascript 能够在数组中存储不同类型的对象的能力是积极的?它在 Java 中基本上用作 Object[],只是没有强制转换。我认为这是一种编码风险。 @shazin 对不起,平凡的对象是什么意思?有什么例子或参考吗?以及为什么数组不会使这种类型的转换成为编译器错误。谢谢。 @Tony 这意味着它不是 100% 的对象,因为它没有任何功能,但它有一个像“长度”这样的字段。它不仅仅是一个前导变量,但还不是一个成熟的对象。 @shazin 嗯,数组扩展 Object。因此,它们是“完全成熟的对象”。毫无疑问。

以上是关于java中cast arraylist和cast array之间的区别[重复]的主要内容,如果未能解决你的问题,请参考以下文章

使用redis时出现java.util.ArrayList cannot be cast to java.lang.Long

PageHelper分页异常(java.base/java.util.ArrayList cannot be cast to com.github.pagehelper.Page)

Type safety: Unchecked cast from Object to ArrayList

何时在 Linq 中使用 Cast() 和 Oftype()

ArrayList cannot be cast to com.github.pagehelper.Page

SQL SERVER中强制类型转换cast和convert的区别