[Java]PTA:(选做) jmu-Java-03面向对象基础-clone方法、标识接口、深拷贝
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())
更多推荐



所有评论(0)