Java中实现浅拷贝最标准方式是实现Cloneable接口并重写public clone()方法,调用super.clone()完成字段逐值复制:基本类型复制值,引用类型仅复制地址;也可用拷贝构造器实现等效浅拷贝。

Java 中实现对象的浅拷贝,最常用且标准的方式是让类实现 Cloneable 接口,并重写 clone() 方法。
实现 Cloneable 接口并重写 clone() 方法
Cloneable 是一个标记接口(无方法),它的作用是告诉 JVM 当前类允许被克隆。如果不实现它就调用 clone(),会抛出 CloneNotSupportedException。
重写的 clone() 方法通常只需调用 super.clone(),JVM 会自动完成字段的逐字段复制(即浅拷贝):
- 基本类型(如
int、boolean)值被直接复制; - 引用类型(如
String、自定义对象、数组)只复制引用地址,新旧对象共享同一份堆内存中的对象。
注意 clone() 的访问权限和异常声明
Object.clone() 是 protected 方法,子类重写时需改为 public 才能被外部调用;同时必须显式处理或声明 CloneNotSupportedException:
public class Person implements Cloneable {
private String name;
private int age;
private Address address; // 引用类型
@Override
public Person clone() {
try {
return (Person) super.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e); // 或直接抛出
}
}
}
浅拷贝的典型表现与验证方式
浅拷贝后,修改原始对象中基本类型字段不影响副本;但修改其引用类型字段的内容(如 address.setCity("Beijing")),副本中看到的也会变——因为它们指向同一个 Address 实例。
可通过比较引用是否相等来验证:
-
original.address == cloned.address→ true(说明是浅拷贝); -
original.name == cloned.name→ 可能为 true(字符串常量池优化),但不具判断意义; -
original.equals(cloned)→ 默认是引用比较,返回 false,除非重写了equals()。
替代方案:构造器传参或静态工厂方法
如果不想依赖 Cloneable(它设计有缺陷,比如无法强制子类正确实现),可用“拷贝构造器”或“静态工厂方法”模拟浅拷贝逻辑:
public Person(Person other) {
this.name = other.name; // 基本类型/不可变对象直接赋值
this.age = other.age;
this.address = other.address; // 引用仍共享,仍是浅拷贝效果
}
这种方式更可控、语义清晰,也避免了 CloneNotSupportedException 和反射调用的隐晦性。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











