对于所有的基本类型都是浅拷贝,不论什么方式;
但对于引用类型,当调用object的clone方法时,除String类型外,其他都为深拷贝;对于String对象类型要实现深拷贝必须要手动创建(new)一个新的String对象;
public class CloneAbleDemo {
public static void main(String[] args) throws CloneNotSupportedException {
CloneAbleImpl cloneAble = new CloneAbleImpl(1);
cloneAble.setS("1");
// 如果当前类未实现CloneAble接口,则会直接抛出CloneNotSupportedException异常信息
CloneAbleImpl clone = cloneAble.clone();
System.out.println(clone.getValue());
//结果为false,深拷贝
System.out.println(cloneAble == clone);
// 当为浅拷贝时,结果为true
// 数据流程为 cloneAble对象的s字段 -> clone对象的s字段; 对于String类型的复制实际默认是浅拷贝
System.out.println(cloneAble.getS() == clone.getS());
// 当为深拷贝时,上述结果为false,而当前结果为true
System.out.println(cloneAble.getS().equals(clone.getS()));
}
}
class CloneAbleImpl implements Cloneable {
private final int value;
private String s;
CloneAbleImpl(int value) {
this.value = value;
}
public int getValue() {
return this.value;
}
public String getS() {
return this.s;
}
public void setS(String s) {
this.s = s;
}
/**
* 重写object中的clone方法,并修改object中的clone的返回值和访问性
*
* @return
* @throws CloneNotSupportedException
*/
@Override
public CloneAbleImpl clone() throws CloneNotSupportedException {
CloneAbleImpl cloneAble = (CloneAbleImpl) super.clone();
// 深拷贝,创建了一个新的String对象,对于s而言此时就是深拷贝
cloneAble.setS(new String(this.s));
return cloneAble;
}
}
通过序列化文件流的方式实现深拷贝
private static ArrayList<String> deepCloneInSerialization(ArrayList<String> arrayList) throws IOException, ClassNotFoundException {
// 操作快照数据,不要在源数据上直接操作
ArrayList<String> ts = new ArrayList<>(arrayList);
// 将数据转换为内存中的输出流
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(ts);
// 从输出流中读取数据转换为输入流
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
// 使用spring 流拷贝工具类
StreamUtils.copy(objectInputStream, objectOutputStream); // 需要依赖于spring-core
return (ArrayList<String>) objectInputStream.readObject();
}