java数组的length是对象头后固定偏移处的独立4字节字段,非对象头组成部分;它由jvm在创建时写死,支持o(1)直接内存访问,与元素类型无关且不可修改。

Java 数组的 length 字段不是“加在对象头里”的额外字段,而是紧挨着对象头之后、位于元素数据之前的一个固定偏移量处的独立字段。它不占用对象头本身的结构空间,但属于数组对象整体内存布局中不可分割的一部分。
对象头本身不含 length,数组长度是单独保留的字段
普通 Java 对象的对象头只包含两部分:
- Mark Word:存储哈希码、锁状态、GC 年龄等运行时信息;
- Klass Pointer:指向类元数据的指针。
这两部分对所有对象通用,不预留任何字段给数组长度。而数组是一种特殊类型——JVM 必须能快速、直接获取其长度,且该长度在创建后不可变。因此 JVM 规范强制要求:所有数组对象在对象头之后、数据开始之前,必须有一个固定大小的 length 字段。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
为什么必须显式存 length,不能从元数据推导?
普通对象的大小可由类定义(字段类型与数量)静态确定,但数组的元素个数在编译期完全未知。例如:
-
new int[10]和new int[1000]是同一类(int[]),元数据完全一样; - JVM 无法仅凭
int[].class知道当前实例含多少个int; - 所以每个数组实例必须自带自己的长度值,供
arraylength字节码指令直接读取。
4 字节长度字段的大小和位置是确定的
该字段始终为 4 字节(32 位),无论 JVM 是 32 位还是 64 位,也无论是否开启压缩指针:
- 在 32 位 JVM 中:对象头共 8 字节(Mark Word 4 + Klass Pointer 4),length 占接下来 4 字节;
- 在 64 位 JVM(开启压缩指针)中:对象头为 12 字节(Mark Word 8 + Klass Pointer 4),length 紧随其后,仍是 4 字节;
- 该字段地址固定偏移,JVM 可通过硬编码偏移(如 +12 或 +16)单次内存读取完成访问,无需方法调用或查表。
这种设计兼顾了效率与一致性
把 length 放在对象头之后而非嵌入头内,有明确工程考量:
- 保持对象头结构统一:普通对象和数组对象共享同一套头格式,仅数组多出一个标准后缀;
- 避免头膨胀:如果为数组扩展对象头,会破坏所有对象的内存对齐和字段偏移约定;
- 零成本访问:字节码指令
arraylength直接按固定偏移取值,比调用 getter 或查元数据快一个数量级。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










