system.arraycopy不抛检查异常,但参数非法时立即抛出runtimeexception:src/dest为null→nullpointerexception;srcpos、destpos或length为负,或越界→arrayindexoutofboundsexception;类型不兼容→arraystoreexception。

System.arraycopy 本身不抛出检查异常(checked exception),但会在参数非法时直接抛出运行时异常(RuntimeException),最常见的是 NullPointerException 和 ArrayIndexOutOfBoundsException。它不会静默失败,也不会返回错误码——出错就立即中断并抛异常。
哪些情况会触发异常?
以下任一条件不满足,都会在调用瞬间抛出异常:
- src 或 dest 为 null → 抛 NullPointerException
- srcPos、destPos 或 length 为负数 → 抛 ArrayIndexOutOfBoundsException
- srcPos + length > src.length → 抛 ArrayIndexOutOfBoundsException
- destPos + length > dest.length → 抛 ArrayIndexOutOfBoundsException
如何安全使用?
推荐在调用前做轻量级校验,避免异常打断流程(尤其在循环或高频调用中):
- 先判空:
if (src == null || dest == null) throw new IllegalArgumentException("Array must not be null"); - 再校长度:
if (length src.length || destPos + length > dest.length)→ 主动提示更明确的错误信息 - 若不确定源/目标类型兼容(如跨子类数组拷贝),注意:如果 src 和 dest 元素类型不兼容(比如把 String[] 拷到 Integer[]),会在运行时抛 ArrayStoreException —— 这个异常发生在拷贝过程中,无法提前完全规避,但可通过类型检查降低风险
异常处理的最佳实践
不要用 try-catch 包裹每次调用(性能损耗且掩盖逻辑问题),而是:
- 在初始化或参数入口处做校验(防御性编程)
- 对已知可能越界的场景(如动态计算索引),提前截断 length:
int actualLen = Math.min(src.length - srcPos, dest.length - destPos); - 日志记录异常时,附带 src.length、dest.length、srcPos、destPos、length 等上下文,便于定位
替代方案参考
如果需要更健壮或语义更清晰的操作,可考虑:
-
Arrays.copyOfRange():自动处理边界,返回新数组,适合“取一段”场景 -
Arrays.copyOf():复制整个数组并可指定新长度,内部也用 arraycopy,但封装了校验 - 流式操作(如
Stream.of().toArray()):适用于需转换或过滤的场景,但性能低于 arraycopy
不复杂但容易忽略
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











