2014-06-27 73 views
2

由于Jon的这个post的回答已经说过,如果编译器允许这个cast(如下所示),稍后添加一些其他对象对于程序来说可能是件坏事。java中cast阵列列表和cast数组之间的区别

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

+0

@ user3580294感谢您的提醒 – Tony

回答

1

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

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

因此铸造数组很好。

但是将Casting ArrayList转换为超级对象,其中底层的ArrayList实现只能容纳一个String(子类)将导致运行时出现问题。

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

此前的Java 1.5的通用

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

是合法的程序员不得不做了很多instanceof检查。他们在运行时无法检查程序崩溃。

+0

半不相关的问题,为什么人们把Javascript的能力存储在数组中的不同类型的对象的能力是积极的?它基本上用作Java中的对象[],只是没有投射。我认为这是一种编码危险。 – EpicPandaForce

+0

@shazin对不起,但什么是世俗的对象是什么意思?任何示例或参考?以及为什么数组不会使这种类型的转换出现编译器错误。谢谢。 – Tony

+0

@Tony这意味着它不是一个100%的对象,因为它没有任何功能,但它有一个像'长度'字段。它不仅仅是一个前置变量,而不是一个完全成熟的对象。 – shazin

0

数组被设计为允许协变赋值,如果数组的组件类型可分配给赋值数组的组件类型。类型检查在运行时由JVM执行,其中ArrayStoreException被抛出,以防将值存储在不兼容的数组中。正确使用,这允许表达阵列的协变类型,这通常很方便。

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