将不同类型的对象放入array会抛出ArrayStoreException
,同时将不同类型的对象放入ArrayList
作品中。
据我所知,ArrayList是建立在数组之上的,为什么它在那里工作?它的实现方式不同吗?
我搜索但没有找到答案。
答案 0 :(得分:6)
ArrayList
有一个名为Object[] elementData
的字段,这意味着ArrayList
支持添加各种对象引用。这也意味着ArrayList
不支持原始类型,例如int
或char
,而是支持其包装类Integer
和Character
。
除非您将它们声明为Object[]
,否则数组通常用于声明它们的单一类型元素。对于原始类型,没有通用数组,只有基元数组int[]
,char[]
和...
如果你创建一个Object []数组,并放入字符串,然后是一个日期对象,它将抛出一个异常
这里的代码通过Object[]
存储String
和Date
来证明相反,编译和执行没有问题:
Object[] objects = { "hello", "world", new Date() };
System.out.println(Arrays.toString(objects));
输出(日期取决于您电脑的当前时间):
[hello, world, Tue Aug 12 00:09:00 GMT 2014]
您可以检查它是否有效here。
答案 1 :(得分:2)
ArrayStoreException
只有在您将数组SomeClass[]
强制转换为数组TheSuperClass[]
时才会出现。在其他情况下不会被抛出。例如:
A[] array = new A[100];
array
的元素可以是类A
的对象或A
的任何子类,您永远不会得到ArrayStoreException
。类似地:
Object[] array = new Object[100];
这个数组的元素可以是任何东西。无论您将array[n]
分配给哪个,都不会抛出ArrayStoreException
。
当您使用new
创建一个类型的数组,然后将其(可能是隐式)转换为某个超类类型的数组时,会出现此问题:
A[] array = new B[100]; // legal if B is a subclass of A
C[] array2 = new C[100];
Object[] array3;
array3 = array2; // legal even though `array2` is C[]
这种演员是合法的。 但是如果您尝试分配的内容不适合用于创建数组的类型,那么您将获得ArrayStoreException
。
array[1] = new A();
可以分配到array[n]
的唯一内容是B
或B
的子类。编译器无法在编译时捕获上述错误,但它会在运行时抛出异常。
array3[1] = "some string";
即使array3
是Object[]
数组,也不能将任何旧对象分配给它的元素;它们必须是C
或C
的子类。
ArrayList
这不是问题的原因是你不能做同样的演员。
ArrayList<A> array = new ArrayList<B>(); // illegal even if B is a subclass of A
ArrayList<C> array2 = new ArrayList<C>();
ArrayList<Object> array3;
array3 = array2; // illegal
因此,数组的限制并不比ArrayList
更严格。在无法提出ArrayList
s的情况下,数组有一个例外。
编辑(基于Luiggi的评论):好的,看起来你可以用一些诡计强迫错误的对象进入ArrayList
:
((ArrayList)array2).add(x);
x
可以有任何类型;它不必是C
类型。但永远,永远,永远不会这样做。特别是在任何程序中,我可能需要维持一天。