【问题标题】:ArrayStoreException when trying to set an element of an array to a superclass object尝试将数组的元素设置为超类对象时出现 ArrayStoreException
【发布时间】:2013-05-30 15:08:01
【问题描述】:
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 对象,该对象小于 (?) B (B extends A)。

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

【问题讨论】:

  • 想想吧。如果Dog extends Animal 则狗是动物,但并非所有动物都是狗。

标签: java arrays object memory compiler-construction


【解决方案1】:

您可以在该对象内存储对象的子类。即B可以存储在A中,但AB类型的超类。基本上,继承链中类X以下的任何类都可以称为类型X,但继承链中类X以上的任何类都不能称为类型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,如果XY 的子类。 (或者子类的子类。是递归定义)。

让我们用一些英文术语

我们用ItemBook 代替AB

public class Item {}

public class Book extends Item {}

现在,这样说是有道理的:

Item b = new Book(); // All Books are items.

这样说是没有意义的:

Book b = new Item(); // All items are definitely not books.

【讨论】:

    【解决方案2】:

    根据Documentation

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

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

    【讨论】:

      【解决方案3】:

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

      如何确定插入的 Animal 是蝴蝶?

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

          【解决方案5】:

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

          【讨论】:

            【解决方案6】:

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

            【讨论】:

              【解决方案7】:

              给定:

              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
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2021-08-25
                • 1970-01-01
                • 2018-03-12
                • 2019-11-05
                • 2016-05-10
                • 1970-01-01
                • 1970-01-01
                • 2020-07-16
                相关资源
                最近更新 更多