Java 深拷贝 List 对象的正确方法及常见错误解析

本文将介绍使用 Java 序列化进行深拷贝 List 对象的正确方法,并分析常见错误 'java.lang.ClassCastException: class java.util.ArrayList cannot be cast to class com.rcqt.server.bean.DetailRouteMapData' 的原因及解决方法。

问题描述

在使用序列化进行深拷贝 List 对象时,可能会遇到以下错误:

Exception in thread "Thread-503" java.lang.ClassCastException: class java.util.ArrayList cannot be cast to class com.rcqt.server.bean.DetailRouteMapData (java.util.ArrayList is in module java.base of loader 'bootstrap'; com.rcqt.server.bean.DetailRouteMapData is in unnamed module of loader 'app')
	at com.rcqt.server.GM.deepCopy(GM.java:1148)
	at com.rcqt.server.GM.lambda$checkIsUploadAndUpdateFileTrain$0(GM.java:919)
	at java.base/java.lang.Thread.run(Thread.java:833)

错误信息表明,代码试图将 ArrayList 对象强制转换为 DetailRouteMapData 对象,导致类型转换异常。

错误原因

错误原因在于以下代码行:

copiedList.add((DetailRouteMapData) in.readObject());

根据异常信息提示,in.readObject() 返回的是一个 ArrayList 对象,无法强制转换为 DetailRouteMapData 对象。这是因为序列化和反序列化操作会将整个 List 对象序列化,而不是每个元素。

正确方法

为了正确地读取集合对象,需要修改代码以直接读取 List 对象:

List<DetailRouteMapData> copiedList = (List<DetailRouteMapData>) in.readObject();

修改后的代码

private List<DetailRouteMapData> deepCopy(List<DetailRouteMapData> originalList) throws IOException, ClassNotFoundException {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();//创建一个字节数组输出流。
    ObjectOutputStream out = new ObjectOutputStream(bos);//创建一个对象输出流,它将把Java对象转换为字节流。
    out.writeObject(originalList);//将原始的列表对象写入到对象输出流中。
    out.flush();//刷新输出流,确保所有的数据都被写入到底层的字节数组中。
    out.close();//关闭对象输出流。

    ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
    ObjectInputStream in = new ObjectInputStream(bis);
    List<DetailRouteMapData> copiedList = (List<DetailRouteMapData>) in.readObject();
    in.close();
    return copiedList;
}

总结

使用 Java 序列化进行深拷贝 List 对象时,需要确保读取的是整个 List 对象,而不是单个元素。修改代码以直接读取 List 对象可以解决 'java.lang.ClassCastException' 错误。

Java 深拷贝 List<DetailRouteMapData> 对象的正确方法及常见错误解析

原文地址: https://www.cveoy.top/t/topic/quyZ 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录