java数组中的ArrayStoreException

时间:2014-06-13 13:59:39

标签: java arrays

这是Core Java

一书中的一个例子

两个班级员工和经理。经理扩展了员工。

下面的代码
Manager[] mans ={new Manager("Adam"),new Manager("Ben")};              
Employee[] emps =mans ;   
emps[0] = new Employee ("Charlie");//throws ArrayStoreException in runtime actually;

作者说在这种情况下,数组中的元素应该保持相同的类型,否则会抛出ArrayStoreException。 在我看来,emps [0]只是对实例'新员工(" Charlie")'的引用。和emps [0]的类型是之前声明的Employee。所以它为什么抛出异常。我的基础知识有问题吗?

3 个答案:

答案 0 :(得分:4)

创建数组时,它会记住它要存储的数据类型。所以如果你有课程

class Employee { .. }
class Manager extends Employee { .. }

您将创建数组

Manager[] arrM = new Manager[10];

数组将记住它只需要存储Manager类或其派生类型的实例。但是这样的数组不能存储超类型的Manager,因为超类型可能没有Manager类的所有方法或字段,所以像

arrM[0] = new Manager();

没问题,但是

arrM[0] = new Employee();

抛出java.lang.ArrayStoreException: Employee指出Employee在这里不正确。

所以在你的情况下,你是

  • 为经理创建数组

    Manager[] mans ={new Manager("Adam"),new Manager("Ben")};
    
  • 使用超类型Employee

    创建对此数组的引用
    Employee[] emps =mans;
    

    (但是这个引用它仍然指向可以容纳仅Menagers 的数组)

  • 并尝试放入数组new Employee

    emps[0] = new Employee("Charlie");
    

但正如我所提到的,这是不允许的,因为员工可能没有与Manager相同的成员。让我们说Menager可以hire(...)某人,而员工不能(没有这种方法)。如果你打电话

会发生什么
    mans[0].hire(new Employee("Tom");

emps[0] = new Employee ("Charlie");不会抛出异常,但会让员工置于emps[0]吗?由于mansemps使用相同的数组,因此意味着mans[0].hire(new Employee("Tom")会从Employee("Charlie")调用,而hire无法雇用任何人,因为员工没有{{1}}方法。

这就是为什么你不能在管理者数组中放置超类型(Employee)的实例。

答案 1 :(得分:0)

在第二行,您可以将子类数组(Manager [] mans)分配给对超类(Employee[] emps)数组的引用。没问题......但是在这一行之后真正的emps类型是

Manager[]

数组的实际类型是在运行时确定的,引用Employee[]引用它是值得的,它是一个Manager的数组。

因此emps[0]应为Manager类型。

答案 2 :(得分:0)

它引发了一个例外,因为正如书中所说,类型是不同的。 Employee[] emps = mans;表示emps中有两个元素Manager。因此,如果添加新元素或替换现有元素,则它必须是相同的类型。

我想知道你是否制作了一个大小为1的数组mans(不知道你会做什么,如果你计划稍后再扩展它可能是ArrayList)然后按照你的其余代码,会发生什么。我敢打赌它仍然不允许你在数组中插入Employee