在 Java 中,默认的克隆机制是浅克隆,这意味着只有对象本身会被复制,而对象内部的引用对象不会被复制。例如,如果对象 A 包含一个引用对象 X,那么克隆后的对象 B 仍然会引用同一个 X 对象。为了实现真正的深度克隆,我们需要手动克隆所有内部引用的对象。
下面是一个深度克隆的示例:
```java
package com.example;
import java.util.Objects;
public class Book implements Cloneable {
private String title;
private double price;
public Book(String title, double price) {
this.title = title;
this.price = price;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return "书名: " + title + " 单价: " + price;
}
}
public class Student implements Cloneable {
private String name;
private String gender;
private Book book;
public Student(String name, String gender, Book book) {
this.name = name;
this.gender = gender;
this.book = book;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Book getBook() {
return book;
}
public void setBook(Book book) {
this.book = book;
}
@Override
protected Object clone() throws CloneNotSupportedException {
Student clOnedStudent= (Student) super.clone();
if (this.book != null) {
clonedStudent.book = (Book) this.book.clone();
}
return clonedStudent;
}
@Override
public String toString() {
return "姓名: " + name + ", 性别: " + gender + "\n借的书: " + book.toString();
}
}
public class Main {
public static void main(String[] args) throws Exception {
Book book = new Book("理想国", 35);
Student studentA = new Student("梅西", "男", book);
// 浅克隆
Student studentB = studentA;
studentA.setName("李娜");
System.out.println("studentA: " + studentA + "\nstudentB: " + studentB);
// 深度克隆
studentB = (Student) studentA.clone();
studentA.setName("梅西");
System.out.println("克隆之后:");
System.out.println("studentA: " + studentA + "\nstudentB: " + studentB);
}
}
```
输出结果:
```
studentA: 姓名: 李娜, 性别: 男
借的书: 书名: 理想国 单价: 35.0
studentB: 姓名: 李娜, 性别: 男
借的书: 书名: 理想国 单价: 35.0
克隆之后:
studentA: 姓名: 梅西, 性别: 男
借的书: 书名: 理想国 单价: 35.0
studentB: 姓名: 李娜, 性别: 男
借的书: 书名: 理想国 单价: 35.0
```
深度克隆的步骤如下:
- 克隆当前对象。
- 克隆当前对象所引用的所有对象。
- 返回克隆后的对象。