Java一维数组初始化体现栈与堆协作:变量在栈,数据在堆;动态初始化先分配堆空间并赋默认值,静态初始化直接写入指定值;数组名是引用,赋值传递地址而非数据。

Java 一维数组初始化直接决定内存中堆与栈的协作方式——数组变量本身在栈中,而真实数据存于堆中;初始化动作(无论是动态还是静态)触发堆空间分配,并将首地址回填给栈中的变量。
动态初始化:先分空间,再赋默认值
写法如 int[] arr = new int[5];。执行时:栈中创建局部变量 arr,堆中立即开辟连续 5 个 int 单元,每个自动设为 0;系统把这块连续内存的起始地址(如 [I@abc123)赋给 arr。此时 arr 不是数据本身,而是通往堆里那片区域的“门牌号”。
- 整型数组默认值为 0,布尔为
false,字符为'\u0000' - 引用类型数组(如
String[])默认值为null,不代表字符串对象,只是空引用 - 数组长度固定,无法扩容;
arr.length返回的就是当初new时指定的数字
静态初始化:值定长度,一步到位
写法如 int[] arr = {10, 20, 30}; 或 int[] arr = new int[]{10, 20, 30};。执行时:栈中仍存变量 arr,堆中直接分配恰好容纳 3 个 int 的连续空间,并把给出的值依次写入;地址同样存入 arr。
- 编译器自动推断长度,无需显式写数字
- 所有元素必须显式提供,不能留空或只写部分
- 若含字符串字面量(如
{"张三", "李四"}),字符串内容存于方法区常量池,数组中只存指向它们的引用
数组名本质是引用,不是数据容器
打印 System.out.println(arr); 输出的是类似 [I@xxx 的哈希码,它由堆中实际内存地址派生而来——这印证了 arr 存储的是地址,而非数值本身。当执行 int[] b = arr;,只是把同一个地址复制给 b,两个变量指向堆中同一块内存。
立即学习“Java免费学习笔记(深入)”;
- 修改
b[0] = 99;,arr[0]也会变成 99 -
arr == b结果为true,因为比较的是地址值 - 若后续让
arr = new int[2];,原堆空间若无其他引用,就进入待回收状态
常见误区与验证技巧
初学者易混淆“变量”和“对象”。可用以下小技巧验证内存行为:
- 用
System.identityHashCode(arr)查看底层地址哈希,比toString()更稳定 - 对引用类型数组,
arr[i] == null判断是否未赋对象,而非arr[i].equals(null) - 访问
arr[-1]或arr[5](超出length)会抛ArrayIndexOutOfBoundsException,这是运行时检查,非编译错误


















