根本原因是运行时组件类型不兼容,而非多态本身;system.arraycopy要求源数组与目标数组的运行时组件类型必须满足isassignablefrom关系,否则抛出arraystoreexception。

Java中对多态对象数组使用System.arraycopy时出现类型不匹配错误,根本原因不是多态本身,而是数组的**运行时组件类型(runtime component type)与目标数组不兼容**。关键要区分“声明类型”和“实际数组类型”。
确认源数组和目标数组的真实类型
System.arraycopy要求源数组和目标数组的组件类型必须兼容(即目标数组组件类型是源数组组件类型的父类或相同类型)。但多态声明容易掩盖真实类型:
- 例如:
Animal[] animals = new Dog[5];—— 声明为Animal[],但运行时数组类型是Dog[] - 若尝试复制到
Cat[] cats = new Cat[5];,即使Dog和Cat都继承Animal,Dog[]与Cat[]互不兼容,会抛ArrayStoreException(复制时)或ArrayStoreException(赋值时),而arraycopy在运行时检查失败会直接报错 - 用
src.getClass().getComponentType()和dest.getClass().getComponentType()打印确认真实组件类型
避免用具体子类数组接收多态引用
如果业务逻辑允许,优先让数组本身保持统一、安全的类型:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 声明并创建为父类数组:
Animal[] animals = new Animal[5];,再存入Dog、Cat等实例 - 这样
animals的真实类型就是Animal[],可安全复制到另一个Animal[]或其父类数组(如Object[]) - 不要写
Animal[] arr = new Dog[10];后再试图复制进Animal[] other = new Animal[10];——虽然编译通过,但运行时arraycopy会因Dog[] → Animal[]被拒绝(JVM禁止将子类数组视为父类数组进行拷贝)
用泛型集合替代原始数组(推荐)
数组的协变性(covariance)是类型不安全的根源。改用List extends Animal>或List<animal></animal>更清晰、安全:
-
List<animal> list = new ArrayList();</animal>可添加任意Animal子类实例 - 复制用
newList.addAll(oldList)或list.subList(...).addAll(...),无类型擦除风险,也无运行时数组类型冲突 - 必要时转回数组:用
list.toArray(new Animal[0]),返回的是真正的Animal[],非子类数组
不得已用arraycopy时的兜底方案
若必须操作原始数组且类型不确定,可先做类型校验或降级处理:
- 检查目标数组是否能容纳源元素:
if (dest.getClass().getComponentType().isAssignableFrom(src.getClass().getComponentType())) - 否则改用循环赋值:
for (int i = 0; i (需确保<code>T是安全上界) - 或统一转成
Object[]中转:Object[] temp = new Object[src.length]; System.arraycopy(src, 0, temp, 0, src.length); System.arraycopy(temp, 0, dest, 0, len);(适用于目标为Object[]或其子类数组)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










