拷贝,通俗点讲就是复制。wins 中使用快捷键 ctrl+c 就能完成。但是在 Java 开发中,并不这么简单。当接口请求的参数传递进来后,规范的开发习惯要求程序员复制一份参数实体进行处理,也就是常用的DTO。直接声明自定义实体,然后使用 = 号进行赋值,只是传递了一个引用给自定义实体,并不能自由处理。那么,深度拷贝,就出现了!
下面,就跟着小编来看下如何进行对象的深度拷贝吧!
一,浅拷贝
public class Test {
@org.junit.Test
public void test1(){
Apple apple = new Apple("ppkk",8);
//1,传递apple引用给apple1
Apple apple1 = apple;
System.out.println("apple:" + apple);
System.out.println("apple1:" + apple1);
//2,修改apple1属性值,其实修改的是引用的属性值,apple会受影响
apple1.setPrice(10);
System.out.println("apple:" + apple);
System.out.println("apple1:" + apple1);
}
}
@Data
@AllArgsConstructor
@ToString
public class Apple {
private String name;
private int price;
}
输出:
D:\jdk\jdk1.8.0_171\bin\java.exe
apple:Apple(name=ppkk, price=8)
apple1:Apple(name=ppkk, price=8)
apple:Apple(name=ppkk, price=10)
apple1:Apple(name=ppkk, price=10)
二,深度拷贝
1,编写拷贝工具类
public class ObjectCloneUtils {
public static <T> T clone (T src){
T result = null;
try (
// 1,开启io字节输出流
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// 2,装配对象输出流程
ObjectOutputStream oos = new ObjectOutputStream(baos);
){
// 3,把src原对象写入输出流中
oos.writeObject(src);
// 4,刷新输出流
oos.flush();
try (
// 5,开启io字节输入流
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
// 6,装配对象输入流
ObjectInputStream ois = new ObjectInputStream(bais);
){
// 7,读取输入流中对象数据
result = (T)ois.readObject();
}
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
return result;
}
}
2,实体对象实现序列化接口,并重写 equals() 方法
public class Apple implements Serializable {
static final long serialVersionUID = 1L;
private String name;
private int price;
public Apple(String name, int price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
//重写 equals() 方法
@Override
public boolean equals(Object obj) {
if (this == obj){
return true;
}
if (obj instanceof Apple){
Apple apple = (Apple) obj;
return this.name.equals(apple.getName()) && this.price == apple.getPrice();
}
return false;
}
}
3,调用
public class Test {
@org.junit.Test
public void test2(){
Apple apple = new Apple("ppkk",8);
Apple appleClone = ObjectCloneUtils.clone(apple);
System.out.println(apple.equals(appleClone));
}
}
4,输出:
D:\jdk\jdk1.8.0_171\bin\java.exe
true