原文链接:https://blog.csdn.net/weixin_39792935/article/details/85703570
最近在做项目时,遇到一个java深拷贝的问题,常见有两种方式:
实现Cloneable接口,并且重写Object类中的clone()方法
实现Serializable接口序列化
详情请移步:Java对象-深拷贝(实现Serializable, Cloneable两种方式)
publicclassDemoimplementsCloneable{
privateString name;
privateString value;
privateDemoInternal demoInternal;
/*省略getter和setter方法*/
@Override
publicDemoclone(){
Demo demo =null;
try{
demo = (Demo)super.clone();//浅复制
}catch(CloneNotSupportedException e) {
e.printStackTrace();
}
demo.demoInternal = demoInternal.clone();//深度复制
returndemo;
}
}
publicclassDemoInternalimplementsCloneable{
privateString internalName;
privateString internalValue;
/*省略getter和setter方法*/
@Override
publicDemoInternalclone(){
DemoInternal demoInternal =null;
try{
demoInternal = (DemoInternal)super.clone();
}catch(CloneNotSupportedException e) {
e.printStackTrace();
}
returndemoInternal;
}
}
importjava.io.ByteArrayInputStream;
importjava.io.ByteArrayOutputStream;
importjava.io.ObjectInputStream;
importjava.io.ObjectOutputStream;
importjava.io.Serializable;
/**
* 通过字节流序列化实现深拷贝,需要深拷贝的对象必须实现Serializable接口
*
*@authorAdministrator
*/
publicclassCloneUtils{
@SuppressWarnings("unchecked")
publicstaticTclone(T obj){
T cloneObj =null;
try{
// 写入字节流
ByteArrayOutputStream out =newByteArrayOutputStream();
ObjectOutputStream obs =newObjectOutputStream(out);
obs.writeObject(obj);
obs.close();
// 分配内存,写入原始对象,生成新对象
ByteArrayInputStream ios =newByteArrayInputStream(out.toByteArray());
ObjectInputStream ois =newObjectInputStream(ios);
// 返回生成的新对象
cloneObj = (T) ois.readObject();
ois.close();
}catch(Exception e) {
e.printStackTrace();
}
returncloneObj;
}
}
上述的两种方式,都是通过一层又一层地深入,实现对象的深度复制。所以,如果您遇到类似于下面的问题时:
我已经实现了java.io.Serializable的接口了,为什么还提示我NotSerializableException?
不要迷惑,一定是您忘记将某一个类实现Serializable接口,排错的方法是,使用try catch捕获异常,e.getMessage会打印出您忘记实现Serializable接口的类名,将该类实现Serializable接口即可。