Java中NPE在数组拷贝中源于未校验null源数组,System.arraycopy、Arrays.copyOf、增强for循环及Stream操作均会因null触发异常,须前置判空或封装安全工具方法。

在 Java 中,NullPointerException(NPE)常出现在数组拷贝操作中,根本原因不是拷贝本身出错,而是源数组为 null 时未做校验,直接传给 System.arraycopy、Arrays.copyOf 或增强 for 循环等方法。
调用 System.arraycopy 前必须判空
System.arraycopy 不会自动检查源数组是否为 null,一旦传入 null,立即抛出 NPE。它只校验数组长度和索引范围,不校验引用本身。
- 错误写法:
System.arraycopy(src, 0, dst, 0, src.length);—— 若src == null,运行时报 NPE - 正确做法:先判断
if (src == null),再决定是跳过拷贝、初始化默认数组,还是抛出更明确的异常(如IllegalArgumentException) - 小技巧:可封装工具方法,统一处理 null 源数组,例如返回空数组或指定默认值
使用 Arrays.copyOf 要留意源参数语义
Arrays.copyOf(T[] original, int newLength) 内部会访问 original.length,因此 original == null 同样触发 NPE。
- 它不等价于“安全拷贝”,只是对非 null 数组的便捷封装
- 若业务允许空数组语义,可用
original == null ? new T[0] : Arrays.copyOf(original, newLength) - 注意:泛型数组(如
String[])不能用Arrays.copyOf(Object[], int)替代,类型擦除可能导致运行时 ClassCastException
增强 for 循环和 Stream 拷贝也需防御性检查
看似安全的操作也可能隐含 NPE:
-
for (T item : array) { ... }—— 若array == null,循环开始即抛异常 -
Arrays.stream(array).toArray()——Arrays.stream对null参数直接 throw NPE - 建议统一前置校验:
Objects.requireNonNull(array, "array must not be null"),或用 Optional 包装后 map 处理
构造新数组时避免依赖可能为 null 的长度源
常见陷阱:用可能为 null 的数组去取 length 创建新数组,例如 new String[src.length]。
- 即使后续没拷贝数据,仅声明新数组也会因
src.length触发 NPE - 应改为:
int len = (src == null) ? 0 : src.length;,再创建new String[len] - 若需保持原始数组结构(如 null 元素保留),拷贝逻辑中也要单独处理 src == null 场景,而非默认填充默认值

















