子类克隆时父类private字段会被object.clone()内存级复制,只要父类实现cloneable;但子类无法直接访问修改这些字段,且浅克隆下private引用类型仍共享对象,父类未实现cloneable则抛clonenotsupportedexception。

子类克隆时,父类的非公开属性(private字段)会被复制,但不是通过子类代码直接访问或赋值实现的,而是由 Object.clone() 底层机制完成的内存级拷贝。
非公开属性实际参与克隆
Java 的 clone() 是 native 方法,它不关心字段的访问修饰符(private、protected 或包级),而是直接按对象在堆内存中的布局,逐字节复制整个实例数据。只要父类实现了 Cloneable,其 private 字段就会被包含在复制范围内。
- 例如:父类中
private String id;和private int version;在调用super.clone()后,新对象中对应字段的值与原对象一致 - 子类无需、也无法在
clone()方法里显式读写这些private字段——它们自动出现在克隆结果中
访问权限不影响内存复制,但影响后续修改逻辑
private 属性能被克隆,不代表子类能直接操作它们。子类仍受封装限制:
- 无法在子类中通过
this.id = ...修改父类private字段(编译报错) - 若父类提供了
protected或 public 的 setter/getter,子类可通过这些方法间接修改克隆后对象的对应状态 - 若父类未提供任何修改入口,该字段在克隆后即为只读(对子类而言)
浅克隆下,非公开引用字段仍共享对象
如果父类的 private 字段是引用类型(如 private List<string> tags;</string>),浅克隆只会复制该引用的地址,而非 tags 列表本身:
- 子类克隆出的对象与原对象,其父类的
private tags字段指向同一个ArrayList实例 - 任一对象修改该列表内容(如
add()),另一方可见——这不是权限问题,而是浅克隆的本质行为 - 要避免共享,需在子类
clone()中手动深克隆该字段(例如:cloned.tags = new ArrayList(this.tags);)
父类未实现 Cloneable 会导致克隆失败
即使子类重写了 clone() 并调用 super.clone(),只要父类(或其任意上层祖先)没实现 Cloneable 接口,运行时就会抛出 CloneNotSupportedException:
- 这是强制性的契约检查,发生在 JVM 层,与字段是否
private无关 - 父类是否声明
private字段,不影响该异常触发逻辑;关键在于它是否“表明自己支持克隆” - 因此,若父类不可控(如第三方库类),不能依赖
super.clone(),需改用构造器复制、序列化等替代方案
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











