尝试将数组元素设置为超类对象时出现ArrayStoreException

时间:2013-06-04 09:22:40

标签: java arrays object memory compiler-construction

class A {}
class B extends A {}

嗨,我正在学习Java,我正在努力理解为什么会这样:

A[] tab = new A[10];
tab[0] = new B();

而不是这个:

A[] tab = new B[10];
tab[0] = new A();

此行A[] tab = new B[10];表示编译器在内存中为B预订了10个位置。 tab[0] = new A()设置tab[0]等于新的A对象,该对象小于(?)而不是BB extends A)。

为什么会出现ArrayStoreException: A错误?它是如何工作的?

7 个答案:

答案 0 :(得分:4)

您可以在该对象内存储对象的子类。即B可以存储在A中,但AB类型的超类。基本上,继承链中类X下面的任何类都可以称为类型X,但继承链中类X之上的任何类都不能称为类型{{ 1}}。

您的示例

X

简而言之,如果A[] tab = new A[10]; // Perfectly fine. Equal objects. tab[0] = new B(); // B is a subclass of A, so this is allowed. A[] tab = new B[10]; // Same principle as above, B is a subclass of A tab[0] = new A(); // A is a SUPERCLASS of B, so it can not be referred to as A X的子类,则Y只能称为X。 (或者是子类的子类。它是一个递归定义)。

让我们使用一些英语术语

让我们拥有YA,而不是BItem

Book

现在,说:

是有道理的
public class Item {}

public class Book extends Item {}

说:

是没有意义的
Item b = new Book(); // All Books are items.

答案 1 :(得分:1)

根据Documentation

  

抛出表示已尝试存储错误   对象类型为对象数组。例如,以下内容   代码生成一个ArrayStoreException:

Object x[] = new String[3]; 
x[0] = new Integer(0);

答案 2 :(得分:1)

“我的动物数组将仅包含蝴蝶(A[] tab = new B[10];)。在数组中添加一个新动物(tab[0] = new A();)。”

如何确定插入的动物是蝴蝶?

答案 3 :(得分:1)

java中的拇指规则是超类引用变量可以指向子类对象而不是反之亦然,如果你考虑一下,那么父类可以指向子类对象是有意义的。 List list = new ArrayList()

答案 4 :(得分:1)

因为如果B扩展A,B具有所有A特征(属性,方法等),加上他自己的。

然后每个B也是A,而A(缺少B的特征)不是B。

答案 5 :(得分:1)

这归结为分层类型系统的最基本属性,即 Liskov替换原则:只要允许A的实例,也允许其任何子类型的实例。数组不是特例。

答案 6 :(得分:1)

假设:

class A { }

class B extends A { }

我们有:

A [] a = new A [10]; // can store A or B objects

A [] b = new B [10]; // can only store B objects