Java 尝试将数组元素设置为超类对象时发生ArrayStoreException

Java 尝试将数组元素设置为超类对象时发生ArrayStoreException,java,arrays,object,memory,compiler-construction,Java,Arrays,Object,Memory,Compiler Construction,大家好,我正在学习Java,我正在努力理解为什么这样做有效: class A {} class B extends A {} 而不是这个: A[] tab = new A[10]; tab[0] = new B(); 此行A[]页签=新建B[10]表示编译器在内存中为B预订了10个位置tab[0]=new A()正在将tab[0]设置为小于B(B扩展A)的新A对象 为什么会出现ArrayStoreException:A错误?它是如何工作的?您可以在对象内部存储对象的子类。ieB可以存储在A中

大家好,我正在学习Java,我正在努力理解为什么这样做有效:

class A {}
class B extends A {}
而不是这个:

A[] tab = new A[10];
tab[0] = new B();
此行
A[]页签=新建B[10]表示编译器在内存中为B预订了10个位置
tab[0]=new A()
正在将
tab[0]
设置为小于
B
B扩展A
)的新
A
对象


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

您可以在对象内部存储对象的子类。ie
B
可以存储在
A
中,但
A
B
类型的超类。基本上,继承链中class
X
下面的任何类都可以称为type
X
,但是继承链中class
X
上面的任何类都不能称为type
X

你的榜样

简而言之,
X
只能被称为
Y
,如果
X
Y
的子类。(或子类的子类。这是一个递归定义)

让我们用一些英语术语

我们用
项目
书籍
代替
A
B

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
现在,可以说:

public class Item {}

public class Book extends Item {}
Item b = new Book(); // All Books are items.
说:

public class Item {}

public class Book extends Item {}
Item b = new Book(); // All Books are items.

抛出以指示已尝试存储错误的 将对象类型放入对象数组中。例如,以下 代码生成ArrayStoreException:

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


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

java中的拇指规则是超类引用变量可以指向子类对象,反之亦然,如果您仔细想想,父类可以指向子类对象是有道理的。List List=new ArrayList()

因为若B扩展了A,B就拥有A的所有特征(属性、方法等),以及他自己的特征


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

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

给定:

Object x[] = new String[3]; 
x[0] = new Integer(0);
我们有:

class A { }

class B extends A { }

想想看。如果
Dog扩展了Animal
,则Dog是一种动物,但并非所有动物都是狗。
A [] a = new A [10]; // can store A or B objects

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