java一维数组声明后不初始化,局部变量编译报错,成员变量默认为null;二维数组是“数组的数组”,非连续内存,每行长度可不同;new int[0]是合法空数组,null则调用即崩。

Java一维数组声明后不初始化会怎样
直接报错,int[] arr;只是声明了引用变量,没分配内存,用之前必须初始化,否则编译通不过(局部变量)或运行时为 null(成员变量)。别指望它自动变成空数组。
常见错误现象:java.lang.NullPointerException 在调用 arr.length 或访问 arr[0] 时抛出。
-
int[] arr = new int[5];→ 分配 5 个int的连续堆内存,元素默认为0 -
int[] arr = {1, 2, 3};→ 等价于new int[]{1, 2, 3},长度由字面量数量决定,只能用于声明+初始化同时发生 - 局部数组不初始化就使用,编译器直接拦住;类字段未显式初始化,值为
null,不是空数组
二维数组不是“矩形”,而是数组的数组
Java 没有真正的二维数组类型,int[][] 是「一维数组,每个元素是 int[] 引用」。这意味着每行长度可以不同,内存不是一块连续区域,而是多个独立的一维数组 + 一个存放它们地址的主数组。
使用场景:稀疏表、三角矩阵、动态行长度(比如保存不同长度的日志记录)。
-
int[][] grid = new int[3][4];→ 主数组长 3,每个元素指向一个长度为 4 的int[],共分配 4×3+1 个对象(1 个主数组 + 3 个子数组) -
int[][] jagged = new int[3][];→ 主数组长 3,但子数组全为null,必须单独初始化每行:jagged[0] = new int[2]; jagged[1] = new int[5]; - 误以为
grid[0].length == grid[1].length总成立?错。只在规则矩阵中才相等,否则可能NullPointerException或ArrayIndexOutOfBoundsException
new int[0] 和 null 的区别很关键
new int[0] 是真实存在的空数组对象,有地址、有 length == 0、可安全调用 .length 或遍历(循环 0 次);null 是什么都没有,任何方法调用或属性访问都崩。
容易踩的坑:把初始化逻辑写在 if 分支里,漏掉 else,导致某些路径下数组仍是 null。
- 返回空结果时,优先返回
new int[0]而非null,避免调用方反复判空 -
Arrays.asList(new int[0])返回的是包含一个int[]的列表,不是空列表 —— 基本类型数组不会被自动拆成元素,这是常见误解点 - 序列化/JSON 库(如 Jackson)对
null和空数组处理不同,前者可能被忽略,后者生成[]
多维数组初始化性能和 GC 压力比你想的大
声明 int[1000][1000] 看似只建一个对象,实际创建了 1001 个对象(1 个外层数组 + 1000 个内层数组),GC 跟踪开销明显高于单层大数组。尤其在高频创建场景(如算法中间结果),容易触发 Minor GC。
替代思路:用一维数组模拟二维布局,靠公式算下标(arr[i * cols + j]),内存更紧凑、缓存友好、GC 更轻。
- 如果行数固定且访问模式是遍历整块,优先选
int[] flat = new int[rows * cols] - 注意边界检查成本:手动算下标要自己写
i ,而 <code>grid[i][j]自带双重检查 -
int[][]各子数组可能分散在堆不同位置,CPU 缓存命中率低;扁平化后数据连续,遍历快 2–3 倍(实测常见于图像处理、数值计算)
真正难的不是语法怎么写,是怎么根据访问模式、生命周期、是否需要动态变长,来选对结构 —— 写完 new int[10][10] 很容易,想清楚它背后是不是真需要 101 个对象,就不那么容易了。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











