java一维数组在内存中连续存放,所有元素紧邻排列,首地址即数组对象地址,下标访问通过“首地址+下标×元素字节数”直接计算,实现o(1)随机访问。

Java 一维数组在内存中是连续存放的,这是它最底层、最关键的特点,直接决定了它的性能表现和使用边界。
为什么说“连续”这么重要?
连续性意味着:数组所有元素在堆内存中一个挨着一个排列,中间不留空隙。比如声明 int[] arr = new int[5];,JVM 会一次性申请一块能容纳 5 个 int(共 20 字节)的连续内存空间。首元素的地址就是整个数组对象的地址,后续每个元素地址可通过“首地址 + 下标 × 单个元素字节数”直接算出。
正因为这个数学关系成立,访问 arr[3] 不需要遍历前 3 个元素——而是瞬间定位,时间复杂度稳定为 O(1)。
连续性带来的实际影响
- 查询快,增删慢:随机读取任意下标极快;但要在中间插入或删除元素,就必须手动移动后续所有元素,开销随长度线性增长
- 长度不可变:内存块一旦分配,大小就固定。扩容不是“拉伸”,而是新建更大数组、复制旧数据、丢弃原数组
- 对内存碎片敏感:大数组可能因找不到足够大的连续空间而抛出 OutOfMemoryError,哪怕总空闲内存充足
- 默认值自动填充:动态初始化时,JVM 直接按类型清零/置空整块内存(如 int 全为 0,String 全为 null)
怎么验证它是连续的?
虽然 Java 不暴露内存地址,但可通过间接方式体会连续性:
- 用 System.identityHashCode(arr) 查看数组对象哈希码(近似首地址),再对比不同长度数组的哈希码趋势(通常相邻长度差值接近元素大小)
- 观察性能差异:遍历 10 万和 1000 万个元素,单次下标访问耗时几乎无差别;但用 ArrayList 在中间 add(0, x) 时,数据量翻十倍,耗时也明显上升
- 理解 arr.length 的本质:它不是计算出来的,而是数组对象头里存的一个字段,源自当初分配的连续块大小
连续 ≠ 可以越界访问
连续性是 JVM 内部实现保障,不等于允许你写 arr[100]。Java 运行时始终检查下标范围,越界立即抛出 ArrayIndexOutOfBoundsException。安全性和连续性并存,是 Java 数组的设计原则。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











