clone() 方法运行时检查 cloneable 接口,未实现则抛 clonenotsupportedexception;cloneable 是无方法的标记接口,仅向 jvm 发出可克隆信号;object.clone() 是 native 方法,执行前强制校验;未实现 cloneable 时即使重写 clone() 并调用 super.clone() 仍会运行时失败;实现 cloneable 后才触发底层内存复制;该机制是 java 的显式授权设计,防止资源类浅拷贝引发状态混乱或泄漏;clone() 绕过构造器,不执行初始化块和构造逻辑,final 字段无法重初始化,且默认为浅拷贝。

因为 clone() 方法在运行时会检查类是否实现了 Cloneable 接口,没实现就直接抛出 CloneNotSupportedException —— 这不是编译期限制,而是 JVM 的运行时安全机制。
Cloneable 是标记接口,不提供任何方法
它本身没有声明任何方法,也不参与多态调用。它的唯一作用是向 JVM 发出信号:“这个类允许被克隆”。Object.clone() 是一个 native 方法,执行前会做这个检查;一旦发现没实现,立刻中断并抛异常。
不实现 Cloneable 就调用 super.clone() 一定会失败
- 哪怕你重写了
clone()方法,并在里面写了super.clone(),只要类没声明implements Cloneable,运行时仍会抛异常 - 这不是语法错误,编译能通过,但一执行就崩
- 反过来,只要实现了
Cloneable,super.clone()才真正触发底层内存复制逻辑
这是设计上的显式授权机制
Java 不希望所有对象默认都能被克隆。比如某些封装了资源(如文件句柄、数据库连接)的对象,浅拷贝可能导致状态混乱或资源泄漏。通过强制实现 Cloneable,要求开发者主动确认“我理解克隆的语义,且已做好准备”。
clone() 绕过构造器,需要额外谨慎
clone() 不走任何构造方法,直接分配内存并复制字段值。这意味着:
-
final字段无法在克隆过程中重新初始化,只能依赖原对象已有值 - 初始化块、构造器中的校验逻辑、监听注册等全部跳过
- 若字段引用可变对象(如
ArrayList、自定义对象),默认只复制地址——这就是浅拷贝,容易引发意外共享
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











