Menu
CoddyTech

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() 方法中同时克隆这些嵌套对象,从而实现深拷贝。

challenge icon

挑战

简单

我们来构建一个文档管理系统,用来演示对象克隆。你将创建一个 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。这能证明克隆确实独立于原文档。

    打印三行:

    1. Original: ,后接原文档的 toString()
    2. Clone: ,后接克隆文档的 toString()
    3. 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)
        
    }
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: Java 在线编译器