clone() 方法
本课属于 Coddy Java 学习旅程的“面向对象编程”单元。第 43 课,共 87 课。
clone() 方法会创建对象的副本。要使用它,你的类必须实现 Cloneable 接口,并重写 Object 类中的 clone() 方法。
public class Person implements Cloneable {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public Person clone() {
try {
return (Person) super.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
}现在,你可以创建对象的独立副本:
Person original = new Person("Alice", 25);
Person copy = original.clone();
// copy 是一个独立的对象,但它的属性值与原对象相同。默认情况下,clone() 执行的是浅拷贝,也就是说,它会复制基本类型的值和引用。如果你的对象包含其他对象作为字段,原对象和克隆对象都会引用相同的嵌套对象。要创建嵌套对象也彼此独立的副本,你需要在 clone() 方法中同时克隆这些嵌套对象,从而实现深拷贝。
挑战
简单我们来构建一个文档管理系统,用来演示对象克隆。你将创建一个 Document 类,它可以通过克隆创建相互独立的副本,让用户能够复制文档,同时保留原文档不变。
你将把代码分成两个文件:
Document.java:创建一个表示文档并支持克隆的类。Document 有三个私有字段:title(String)、author(String)和version(int)。添加一个构造函数来初始化所有字段,并为每个字段添加 getter 方法。再添加一个setVersion(int version)方法来更新版本号。让你的 Document 类实现
Cloneable接口,并重写clone()方法,使其返回一个Document。在方法内部捕获CloneNotSupportedException,并将其包装在RuntimeException中。重写
toString(),使其返回:Document[title=X, author=Y, version=Z],其中 X、Y 和 Z 是实际的字段值。Main.java:通过创建并克隆文档,让你的 Document 类发挥作用。你将收到三个输入:标题(String)、作者(String)和版本号(int)。使用这些值创建一个原始 Document,然后克隆它来创建副本。克隆后,使用
setVersion()将副本的版本号加 1。这能证明克隆确实独立于原文档。打印三行:
Original:,后接原文档的 toString()Clone:,后接克隆文档的 toString()Independent:,后接true或false,用于表示原文档和克隆文档是否为不同的对象(使用!=比较)
你将收到三个输入:文档标题(String)、作者姓名(String)和版本号(int)。
注意,修改克隆文档的版本号后,原文档仍然保持不变。这证明 clone() 创建了一个真正独立的副本!
亲手试试
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 读取输入
String title = scanner.nextLine();
String author = scanner.nextLine();
int version = scanner.nextInt();
// TODO: 用输入值创建一个原始 Document 对象
// TODO: 克隆原始文档,创建一个副本
// TODO: 将克隆文档的版本号加 1
// TODO: 先打印 "Original: ",再打印原始文档
// TODO: 先打印 "Clone: ",再打印克隆文档
// TODO: 先打印 "Independent: ",再打印 true/false(检查 original != clone)
}
}这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
7特殊方法与 Object 类
toString() 方法equals() 和 hashCode()clone() 方法compareTo() 和 ComparableComparator 接口回顾:自定义排序自己练习: Java 在线编译器