深拷贝的几种方式
先准备了一些测试类,Student,School类
package clonePackage.deepcopy;
import java.io.Serializable;
public class Student implements Serializable {
private String id;
private int age;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"id='" + id + ''' +
", age=" + age +
'}';
}
}
package clonePackage.deepcopy;
import java.io.Serializable;
import java.util.List;
public class School implements Serializable {
private String name;
private List<Student> students;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
@Override
public String toString() {
return "School{" +
"name='" + name + ''' +
", students=" + students +
'}';
}
}
1.自己实现一个拷贝的工具类。
要拷贝的类必须实现Serializable接口。
工具类如下:
package clonePackage;
import java.io.*;
public class DeepCopyUtil {
public static <T> T deepClone(T obj) {
T cloneObj = null;
try {
//写入字节流
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream obs = new ObjectOutputStream(out);
obs.writeObject(obj);
obs.close();
//分配内存,写入原始对象,生成新对象
ByteArrayInputStream ios = new ByteArrayInputStream(out.toByteArray());
ObjectInputStream ois = new ObjectInputStream(ios);
//返回生成的新对象
cloneObj = (T) ois.readObject();
ois.close();
} catch (Exception e) {
e.printStackTrace();
}
return cloneObj;
}
}
测试代码:
@Test
public void test() {
School school = new School();
school.setName("西安第一小学");
Student student = new Student();
student.setAge(10);
student.setId("1");
List<Student> students = new ArrayList<>();
students.add(student);
school.setStudents(students);
// 开始克隆
School clone = DeepCopyUtil.deepClone(school);
System.out.println("修改前:");
System.out.println("school:" + school);
System.out.println("clone:" + clone);
System.out.println("----------------------------------------------------------------");
clone.getStudents().get(0).setId("2");
clone.getStudents().get(0).setAge(20);
System.out.println("修改后:");
System.out.println("student:" + school);
System.out.println("clone:" + clone);
}
测试结果:
修改前:
school:School{name='西安第一小学', students=[Student{id='1', age=10}]}
clone:School{name='西安第一小学', students=[Student{id='1', age=10}]}
------------------------------------------------------------------------
修改后:
school:School{name='西安第一小学', students=[Student{id='1', age=10}]}
clone:School{name='西安第一小学', students=[Student{id='2', age=20}]}
Process finished with exit code 0
2.使用SerializationUtils
要拷贝的类必须实现Serializable接口。
导入依赖
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
测试代码:
@Test
public void testSerializationUtils() {
School school = new School();
school.setName("西安第一小学");
Student student = new Student();
student.setAge(10);
student.setId("1");
List<Student> students = new ArrayList<>();
students.add(student);
school.setStudents(students);
// 开始克隆
School clone = SerializationUtils.clone(school);
System.out.println("修改前:");
System.out.println("school:" + school);
System.out.println("clone:" + clone);
System.out.println("-------------------------------------------------------------------");
clone.getStudents().get(0).setId("2");
clone.getStudents().get(0).setAge(20);
System.out.println("修改后:");
System.out.println("student:" + school);
System.out.println("clone:" + clone);
}
测试结果:
修改前:
school:School{name='西安第一小学', students=[Student{id='1', age=10}]}
clone:School{name='西安第一小学', students=[Student{id='1', age=10}]}
------------------------------------------------------------------------
修改后:
student:School{name='西安第一小学', students=[Student{id='1', age=10}]}
clone:School{name='西安第一小学', students=[Student{id='2', age=20}]}
Process finished with exit code 0
3.GSON
无需实现Serializable接口。
需导入依赖
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
测试代码:
@Test
public void testGson() {
School school = new School();
school.setName("西安第一小学");
Student student = new Student();
student.setAge(10);
student.setId("1");
List<Student> students = new ArrayList<>();
students.add(student);
school.setStudents(students);
// 开始克隆
Gson gson = new Gson();
School clone = gson.fromJson(gson.toJson(school), School.class);
System.out.println("修改前:");
System.out.println("school:" + school);
System.out.println("clone:" + clone);
System.out.println("----------------------------------------------------------------");
clone.getStudents().get(0).setId("2");
clone.getStudents().get(0).setAge(20);
System.out.println("修改后:");
System.out.println("student:" + school);
System.out.println("clone:" + clone);
}
测试结果:
修改前:
school:School{name='西安第一小学', students=[Student{id='1', age=10}]}
clone:School{name='西安第一小学', students=[Student{id='1', age=10}]}
------------------------------------------------------------------------
修改后:
student:School{name='西安第一小学', students=[Student{id='1', age=10}]}
clone:School{name='西安第一小学', students=[Student{id='2', age=20}]}
Process finished with exit code 0
4.Jackson
无需实现Serializable接口。
需导入依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.0</version>
</dependency>
测试代码:
@Test
public void testjackson() throws IOException {
School school = new School();
school.setName("西安第一小学");
Student student = new Student();
student.setAge(10);
student.setId("1");
List<Student> students = new ArrayList<>();
students.add(student);
school.setStudents(students);
// 开始克隆
ObjectMapper mapper = new ObjectMapper();
School clone = mapper.readValue(mapper.writeValueAsString(school), School.class);
System.out.println("修改前:");
System.out.println("school:" + school);
System.out.println("clone:" + clone);
System.out.println("----------------------------------------------------------------");
clone.getStudents().get(0).setId("2");
clone.getStudents().get(0).setAge(20);
System.out.println("修改后:");
System.out.println("student:" + school);
System.out.println("clone:" + clone);
}
测试结果:
修改前:
school:School{name='西安第一小学', students=[Student{id='1', age=10}]}
clone:School{name='西安第一小学', students=[Student{id='1', age=10}]}
------------------------------------------------------------------------
修改后:
student:School{name='西安第一小学', students=[Student{id='1', age=10}]}
clone:School{name='西安第一小学', students=[Student{id='2', age=20}]}
Process finished with exit code 0