Object的clone方法可以帮助我们克隆对象。现在需编写一个类Car包含:

1.属性:

private String name;
private CarDriver driver;
private int[] scores;

2.无参构造函数

public Car() {
}

3.方法:

@Override
public String toString() {
    return "Car [name=" + name + ", driver=" + driver + ", scores=" + Arrays.toString(scores) + "]";
}

setter/getter方法与clone方法。注意:clone方法需实现对象的深度克隆。

CarDriver为已经定义好的类,部分代码如下:

class CarDriver {
    private String name;
    public CarDriver() {}
    //setter/getter
    //toString    
}

/* 请在这里填写答案,即Car类的完整代码 */

代码如下:

class Car implements Cloneable {
    // 属性
    private String name;
    private CarDriver driver;
    private int[] scores;
    // 无参构造函数
    public Car() {
    }
    // getter和setter方法
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public CarDriver getDriver() {
        return driver;
    }
    public void setDriver(CarDriver driver) {
        this.driver = driver;
    }
    public int[] getScores() {
        return scores;
    }
    public void setScores(int[] scores) {
        this.scores = scores;
    }
    // 重写clone方法实现深拷贝
    @Override
    public Car clone() throws CloneNotSupportedException {
        // 先进行浅拷贝
        Car cloned = (Car) super.clone();
        
        // 深拷贝CarDriver:创建新对象并复制属性
        if (this.driver != null) {
            CarDriver newDriver = new CarDriver();
            newDriver.setName(this.driver.getName()); // 复制name属性
            cloned.setDriver(newDriver);
        }
        // 深拷贝数组
        if (this.scores != null) {
            cloned.scores = Arrays.copyOf(this.scores, this.scores.length);
        }
        // String类型本身不可变,无需额外处理
        return cloned;
    }
    @Override
    public String toString() {
        return "Car [name=" + name + ", driver=" + driver + ", scores=" + Arrays.toString(scores) + "]";
    }
}

学习记录:

1、clone() 方法

clone() 方法是 Object 类中定义的一个原生方法,所有 Java 类都默认继承了这个方法。
Object 类中 clone() 方法的声明如下:

protected native Object clone() throws CloneNotSupportedException;

注意:
1)访问修饰符是 protected:这意味着如果子类不重写 clone() 方法并修改访问权限(通常改为 public),则只能在同一个包或子类中调用该方法。
2)需要实现 Cloneable 接口:Cloneable 是一个标识接口(无任何方法),如果类没有实现它,调用 clone() 会抛出 CloneNotSupportedException。
3)默认浅拷贝:Object 类的 clone() 方法默认实现的是浅拷贝—— 对于基本类型属性会复制值,对于引用类型属性只会复制引用(两个对象共享同一个引用指向的实例)。
4)返回值是 Object 类型:因此重写时通常需要进行类型强转,例如 Car cloned = (Car) super.clone();

2、重写clone()方法的语法格式
// 1. 实现Cloneable接口(标识接口,无方法)
public class 类名 implements Cloneable {
    // 成员变量...
    
    // 2. 重写clone()方法,修改访问权限为public
    @Override
    public 类名 clone() throws CloneNotSupportedException {
        // 3. 调用父类(Object)的clone()方法完成基础拷贝
        类名 克隆对象 = (类名) super.clone();
        
        // 4. (可选)如果需要深拷贝,这里补充引用类型成员的克隆逻辑
        // 例如:克隆对象.引用类型成员 = 原对象.引用类型成员的拷贝;
        
        return 克隆对象;
    }
}

注意:

1)要实现 Cloneable 接口:这是一个 “标识接口”(无任何方法),仅用于告诉 JVM:该类允许被克隆。如果不实现此接口,调用 clone() 会抛出 CloneNotSupportedException。
2)重写 clone() 方法:

  • 必须声明抛出CloneNotSupportedException(或在方法内捕获)。
  • 访问权限从 Object 类的 protected 改为 public,否则外部无法调用。
  • 返回值从 Object 改为当前类类型,避免外部强转。

3)调用 super.clone() :这是克隆的核心步骤,Object 类的 clone() 会创建一个新对象,并将原对象的所有成员变量值(包括基本类型和引用类型的引用)复制到新对象中(浅拷贝)。
4)若是深拷贝:需要处理引用类型成员对于引用类型(如对象、数组等),super.clone() 只会复制引用(浅拷贝)。若要深拷贝,需为这些成员单独创建副本,例如:

  • 数组:使用 Arrays.copyOf() 或 System.arraycopy()
  • 自定义对象:调用该对象的 clone() 方法(需确保其也实现了 Cloneable 并正确重写 clone())
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐