这是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。所以它为什么抛出异常。我的基础知识有问题吗?
答案 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]
吗?由于mans
和emps
使用相同的数组,因此意味着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
。