在Java中,将ArrayList转换为数组和将数组转换为ArrayList之间存在差异。

51 浏览
0 Comments

在Java中,将ArrayList转换为数组和将数组转换为ArrayList之间存在差异。

这个问题已经有答案了

为什么数组是协变的,但泛型是不变的?

正如这个帖子中Jon的回答所说,如果编译器允许下面的强制转换,后面再添加一些其他的对象可能会对程序产生不良影响。

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


但是让我困惑的是,在同样的情况下,数组的行为不同。

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

所以,有人能解释一下这里的区别和为什么Java要做这样的设计吗?谢谢。编辑:一个类似的问题

admin 更改状态以发布 2023年5月21日
0
0 Comments

数组设计时允许协变赋值,如果数组的元素类型可以赋值给被赋值数组的元素类型。类型检查在JVM运行时进行,如果试图存储不兼容数组中的值,就会抛出一个 ArrayStoreException 异常。如果使用正确,这使得数组的协变类型表达更方便。

然而,这个语言特性可能会导致模糊的运行时异常,Sun不想在Java 5中引入泛型类型赋值时重复这种情况。相反,Sun希望在编译时发现这种无效的使用。这似乎尤其重要,因为泛型引入了一个比数组类型更复杂的类型系统组件,如果Sun决定不同,那么类似于 ArrayStoreException 的运行时错误肯定会变得更加普遍。相反,在泛型中,通配符解决了协变和逆变的问题,这使得可以在编译时而不是运行时发现类型错误。

0
0 Comments

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

如果你试图将一个整数赋值给临时数组,它会抛出一个 ArrayStoreException

所以转换数组是可以的。

但是将 ArrayList 强制转换为只能保存字符串的超级对象(子类)的基础 ArrayList 实现将在运行时引起问题。

感谢泛型,编译器可以在发生错误之前识别它,并显示一个编译器错误。如果没有这个设计,程序将在运行时失败。

在Java 1.5之前的泛型。

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

是合法的,但是编码人员必须进行很多 instanceof 检查。如果他们漏检了程序将在运行时崩溃。

0