Java数组初始化只有两种本质方式:声明时直接赋值(静态初始化)或先声明后用new分配空间再赋值(动态初始化);前者适用于编译期已知元素和长度的场景,后者适用于运行时确定长度的场景。

Java数组初始化只有两种本质方式:声明时直接赋值,或先声明后用new分配空间再赋值——其他写法都是这两种的语法糖或组合。
声明同时初始化(静态初始化)
适用于已知所有元素值、且数量固定的场景。编译期就能确定长度,JVM自动推导类型和大小。
- 必须用大括号
{}包裹元素,且不能跟new混用,否则编译报错:illegal start of expression - 数组类型由元素类型决定,例如
int[] arr = {1, 2, 3};中arr是int[],不是Object[] - 不能省略大括号:写成
int[] arr = 1, 2, 3;会直接编译失败 - 支持嵌套初始化,如二维数组:
int[][] matrix = {{1, 2}, {3, 4}};,此时每行长度可不同(不规则数组)
先声明后用new初始化(动态初始化)
适用于运行时才确定长度、或需复用同一类型不同大小数组的场景。内存分配发生在运行时。
- 必须显式指定长度,例如
int[] arr = new int[5];,此时所有元素被初始化为0(数值类型)或null(引用类型) - 长度可以是变量或表达式,但必须是非负整数;若为负数,运行时抛出
NegativeArraySizeException - 不能在
new后加初始化器:new int[3] {1, 2, 3}非法;要写成new int[]{1, 2, 3}(此时等价于静态初始化) - 对对象数组,
new String[3]只创建了3个null引用,不调用String构造函数
匿名数组与方法传参场景
当需要临时构造数组并立即传给方法时,常用匿名数组语法,它本质是new + 初始化器的简写。
立即学习“Java免费学习笔记(深入)”;
- 例如调用
Arrays.asList(new Integer[]{1, 2, 3})可简化为Arrays.asList(1, 2, 3),但注意这是varargs机制,底层仍生成数组 - 直接写
method(new int[]{1, 2, 3})是合法的,new int[]{...}就是匿名数组,没有变量名,作用域仅限该语句 - 不能把匿名数组赋给已有变量再修改:如
int[] a = new int[]{1}; a = new int[]{2};是重新赋值,原数组会被GC,不是“修改”
常见陷阱:多维数组的new写法差异
二维数组初始化最容易混淆的是new位置和维度绑定关系,错误会导致NullPointerException或意外的null引用。
-
int[][] arr = new int[2][3];:创建2×3的矩形数组,所有元素为0 -
int[][] arr = new int[2][];:只分配第一维(2个引用),第二维全为null;后续必须逐行arr[0] = new int[3];,否则访问arr[0][0]会NPE -
int[][] arr = {{1,2}, {3}};:静态初始化,等价于new int[][]{{1,2}, {3}},生成不规则数组 - 不要写
int[] arr[] = new int[][3];——编译错误,第二维长度不能脱离第一维独立指定
真正容易被忽略的是:数组一旦创建,长度就不可变;所谓“扩容”只能靠Arrays.copyOf新建数组并复制,原始数组对象本身不会改变。初始化方式选错,往往在后续扩容或类型转换时才暴露问题。









