Cloneable接口与clone方法---java
浅拷贝
我们知道,在浅拷贝的时候当前类必须实现 Cloneable 接口并重写 clone() 方法,,那么为什么必须实现 Cloneable 接口并重写 clone() 方法呢?
我们首先看一下Cloneable接口,可以看到 Cloneable 接口没有任何方法
package java.lang;
/**
* @author unascribed
* @see java.lang.CloneNotSupportedException
* @see java.lang.Object#clone()
* @since JDK1.0
*/
public interface Cloneable {
}
我们再看看位于Object类中的clone()这个函数方法。
protected native Object clone() throws CloneNotSupportedException;
首先是对这个方法的介绍,它是一个native标记的方法,它返回的是对该对象Object的拷贝。可能会出现CloneNotSupportedException异常。
为什么实现 Cloneable 接口
Cloneable 接口没有任何方法,它的唯一作用是 告知 JVM:某个类允许被克隆。
当你调用 obj.clone() 时,JVM 底层会检查 obj 的类是否实现了 Cloneable 接口
历史来源
Java 1.0 的设计者希望通过标记接口(而非注解,当时注解还未出现)让开发者显式声明类的克隆能力。
如果没有 Cloneable 接口,所有对象默认都可以被克隆,这可能带来安全隐患(例如克隆本应不可变的对象)。
为什么重写 clone 方法
这与 protected 修饰导致的权限问题有关
假设有一个类 MyClass(未重写 clone(),但实现了 Cloneable):
package com.example;
public class MyClass implements Cloneable {
// 未重写 clone()
}
尝试在另一个包中调用 clone():
package another.package;
public class Test {
public static void main(String[] args) {
MyClass obj = new MyClass();
obj.clone(); // 编译错误:clone() has protected access in Object
}
}
关键限制:即使 MyClass 是 Object 的子类,跨包时无法直接通过子类实例访问父类的 protected 方法(除非子类重写并暴露该方法)
,跨包时连子类实例都无法访问自己的 protected 方法