一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

System.arraycopy 的内部异常机制解读

时间:2026-06-18 08:33:47 编辑:袖梨 来源:一聚教程网

System.arraycopy不预检查,异常由JVM执行时实时触发:null参数立即抛NullPointerException;索引或长度越界抛IndexOutOfBoundsException;类型不兼容在复制中抛ArrayStoreException。

System.arraycopy 不做预检查,异常全靠 JVM 在执行时实时触发。它是个 native 方法,底层由 C/C++ 实现,调用时直接进入内存操作阶段——参数合法与否,不是靠“提前判断”,而是靠复制过程中的地址计算和边界比对来决定是否抛异常。

三类异常的触发时机与条件

它会明确抛出三种受检(实际为运行时)异常,每种对应一类硬性违规:

  • IndexOutOfBoundsException:当任意一个数值参数越界时立即抛出
    具体包括:
    • srcPos < 0 或 destPos < 0 或 length < 0
    • srcPos + length > src.length
    • destPos + length > dest.length
  • NullPointerException:只要 src 或 dest 任一为 null,不等开始复制就抛出
    注意:null 检查优先级最高,早于所有索引检查
  • ArrayStoreException:仅在复制过程中发现类型不兼容时抛出
    例如:把 String[] 往 Integer[] 里拷,或 Object[](含 String 和 Date)往 String[] 拷,遇到第一个无法转型的元素即中断并抛异常;此时部分元素可能已写入目标数组

它不处理的“伪异常”场景

有些看似异常的行为,其实不属于它的责任范围:

  • 不校验数组内容:比如源数组某位置是 null,它照常复制过去,不会报错
  • 不防止逻辑越界:length 算错、srcPos 动态计算未同步更新边界——这些属于调用方逻辑缺陷,arraycopy 只忠实地执行你给的数字
  • 不介入反序列化流程:它不能修复字节流解析错误、类版本不匹配或恶意偏移,只在反序列化完成后的数组操作中起作用

为什么 catch 住 IndexOutOfBoundsException 往往治标不治本

捕获这个异常本身没错,但暴露的是设计漏洞:

  • 异常发生时,目标数组可能已被部分写入(尤其跨数组拷贝),状态不可逆
  • 每次靠 try-catch 弥补,不如在调用前用 if 显式校验三个关键不等式:
    srcPos ≥ 0 && srcPos + length ≤ src.length
    destPos ≥ 0 && destPos + length ≤ dest.length
    length ≥ 0
  • 真正健壮的做法是封装 safeArrayCopy 工具方法,把校验收口,让业务代码专注逻辑而非边界防御

Android 低版本上的特殊风险:NoSuchMethodError

这不是 arraycopy 本身的异常机制问题,而是平台兼容性陷阱:

  • Android 5.0(API 21)起新增了 byte[] 专用重载方法
  • 若编译时 targetSdkVersion ≥ 21,又未显式指定使用 Object 版本,dex 编译器可能引用新签名
  • 运行在 Android 4.4(API 19)设备上时,找不到该方法签名,直接 Crash
  • 解法:强制调用原始 Object 版本,或统一用 Arrays.copyOf 替代复杂场景

热门栏目