java深复制的方法
Java中的深复制是指在复制对象时,不仅复制对象本身的属性值,还复制对象所引用的其他对象。在进行深复制时,需要确保被引用的其他对象也进行了复制,而不是简单地拷贝引用。本文将介绍几种常见的Java深复制方法。
一、使用clone()方法实现深复制
Java中的Object类提供了一个clone()方法,可以用于复制对象。但是默认情况下,clone()方法是浅复制的,即只复制对象本身的属性值,而不复制对象所引用的其他对象。为了实现深复制,需要对clone()方法进行重写。
示例代码如下: ```java
public class Student implements Cloneable { private String name; private Course course;
public Student(String name, Course course) { this.name = name; this.course = course; }
@Override
public Object clone() throws CloneNotSupportedException {
Student student = (Student) super.clone(); student.course = (Course) course.clone(); return student; }
// 省略getter和setter方法 }
public class Course implements Cloneable { private String name;
public Course(String name) { this.name = name; }
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone(); }
// 省略getter和setter方法
}
public class Main { public
static
void
main(String[]
args)
throws
CloneNotSupportedException {
Course course = new Course(\"Math\");
Student student1 = new Student(\"Tom\
Student student2 = (Student) student1.clone(); student2.setName(\"Jerry\");
student2.getCourse().setName(\"English\");
System.out.println(\"student1: \" + student1.getName() + \" - \" + student1.getCourse().getName());
System.out.println(\"student2: \" + student2.getName() + \" - \" + student2.getCourse().getName()); } } ```
运行结果: ```
student1: Tom - Math student2: Jerry - English
```
在上述示例代码中,Student类和Course类都实现了Cloneable接口,并重写了clone()方法。在Student类的clone()方法中,除了复制对象本身的属性值外,还通过调用course对象的clone()方法实现了course对象的复制。这样,当修改student2对象的course对象时,不会影响到student1对象的course对象。
二、使用序列化实现深复制
Java中的序列化机制也可以实现对象的深复制。通过将对象序列化为字节流,再将字节流反序列化为对象,实现对象的复制。需要注意的是,被复制的对象及其引用的其他对象都需要实现Serializable接口。
示例代码如下: ```java
import java.io.*;
public class Student implements Serializable { private String name; private Course course;
public Student(String name, Course course) { this.name = name;
this.course = course; }
public Student deepClone() throws IOException,
ClassNotFoundException { ByteArrayOutputStream ByteArrayOutputStream(); ObjectOutputStream ObjectOutputStream(baos); oos.writeObject(this);
baos = new
oos = new
ByteArrayInputStream bais = new
ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais); return (Student) ois.readObject(); }
// 省略getter和setter方法 }
public class Course implements Serializable { private String name;
public Course(String name) {
this.name = name; }
// 省略getter和setter方法 }
public class Main {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Course course = new Course(\"Math\");
Student student1 = new Student(\"Tom\
Student student2 = student1.deepClone(); student2.setName(\"Jerry\");
student2.getCourse().setName(\"English\");
System.out.println(\"student1: \" + student1.getName() + \" - \" + student1.getCourse().getName());
System.out.println(\"student2: \" + student2.getName() + \" - \" + student2.getCourse().getName()); } } ```
运行结果: ```
student1: Tom - Math student2: Jerry - English ```
在上述示例代码中,Student类和Course类都实现了Serializable接口。在Student类中,通过将对象写入字节流并再次读取字节流的方式实现了对象的复制。同样,当修改student2对象的course对象时,不会影响到student1对象的course对象。
三、使用第三方库实现深复制
除了手动实现深复制外,还可以使用一些第三方库来简化深复制的过程。例如,Apache Commons Library中的SerializationUtils类提供了一个clone()方法,可以用于深复制对象。
示例代码如下: ```java
import org.apache.commons.lang3.SerializationUtils;
public class Student implements Serializable { private String name; private Course course;
public Student(String name, Course course) { this.name = name; this.course = course; }
// 省略getter和setter方法 }
public class Course implements Serializable { private String name;
public Course(String name) { this.name = name; }
// 省略getter和setter方法 }
public class Main {
public static void main(String[] args) { Course course = new Course(\"Math\");
Student student1 = new Student(\"Tom\
Student student2 = SerializationUtils.clone(student1); student2.setName(\"Jerry\");
student2.getCourse().setName(\"English\");
System.out.println(\"student1: \" + student1.getName() + \" - \" + student1.getCourse().getName());
System.out.println(\"student2: \" + student2.getName() + \" - \" + student2.getCourse().getName()); } } ```
运行结果: ```
student1: Tom - Math student2: Jerry - English ```
在上述示例代码中,通过调用SerializationUtils类的clone()方法实现了对象的深复制。当修改student2对象的course对象时,不会影响到student1对象的course对象。
总结:
本文介绍了几种常见的Java深复制方法,包括使用clone()方法、使用序列化和使用第三方库。在实际开发中,根据具体的需求选择合适的深复制方法,并确保被复制的对象及其引用的其他对象都能
正确地进行复制,以避免出现意外的问题。