关于对Java中数组的引用

问题描述

《 Core Java Volume I》一书中的一个例子

super

super将导致ArrayStoreException,因为该数组存储了错误的对象。 我给出了数组的内存图:

enter image description here

我认为变量public class Employee { ... } public class Manager extends Employee { ... } Manager[] managers = new Manager[3]; Employee[] staff = managers; //OK staff[0] = new Employee(); //error 存储staff [0]的地址(就像c ++,在staff[0]中,变量staff存储数组的第一个元素的地址)。

因为int *p = new int[3]等于p,所以它们指向相同的内存位置,所以当您编写语句staff时,我认为它等于语句{{1 }},对父项的引用指向子对象是错误的。

我不确定我是否正确,我希望知道对数组的引用(工作人员/经理)与各个数组元素(managersstaff[0] = new Employee() ... ),managers[0] = new Employee()是否可以告诉我数组中第一个元素在内存中的位置。

我还想知道,对于staff[0]staff[1]这样的不同对象数组,它们是否占用相同的内存大小。对不同对象的引用占用相同的内存量吗?

解决方法

我希望了解对数组(职员/经理)的引用与各个数组元素(staff[0]staff[1] ...)之间的关系,staff是否可以告诉我数组中第一个元素在内存中的位置。

在Java中,单个数组元素是数组对象中的变量,如section 10 in the language specification中所述。在语言级别上,没有内存地址或指针算术。该语言不会告诉您staff[0]staff[1]staff的内存地址之间是否存在任何关系-取决于实现。

关于实现的工作方式,来自AlekseyShipilёv(JOL的原始作者)的这篇文章非常有用:https://shipilev.net/jvm/objects-inside-out/

总而言之,数组对象的内存布局包括一个指向对象类的指针,一个有助于垃圾回收和并发的“标记词”,数组的长度(项目数),以及数组元素本身。

由于有“对象标头”,因此工作人员[0]与工作人员的地址不同。但是区别是JVM知道一个数字,因此它可以生成使用航位推算来访问数组元素的高效代码。

关于如何抛出ArrayStoreException:创建new Manager[3]之类的对象数组时,JVM设置类指针,以便它引用“管理器数组”类(如果(尚不存在,而是动态创建的)。当您存储对数组的对象引用时,JVM使用此类指针检查引用是否与数组组件类型兼容,如果不兼容则抛出ArrayStoreException

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...