Java不提供克隆(复制)对象的自动机制。克隆对象意味着逐位复制对象的内容。要支持克隆操作,请在类中实现clone()
方法。Object
类中的clone()
方法的声明如下:
protected Object clone() throws CloneNotSupportedException
clone()
方法声明为protected
。 因此,不能从客户端代码调用它。以下代码无效:
Object obj = new Object()
Object clone = obj.clone() // Error. Cannot access protected clone() method
需要在类中声明clone()
方法为public
来克隆类的对象。
它的返回类型是Object
。 这意味着将需要使用clone()
方法转换返回值。
假设MyClass
是可克隆的。 克隆代码将如下所示
MyClass mc = new MyClass()
MyClass clone = (MyClass)mc.clone() // Need to use a cast
Object
类中的clone()
方法会抛出CloneNotSupportedException
。要调用clone()
方法,需要将调用放在try-catch
块中,或者重新抛出异常。
示例
以下代码显示了如何实现克隆方法。
class MyClass implements Cloneable {
private double value
public MyClass(double value) {
this.value = value
}
public void setValue(double value) {
this.value = value
}
public double getValue() {
return this.value
}
public Object clone() {
MyClass copy = null
try {
copy = (MyClass) super.clone()
} catch (CloneNotSupportedException e) {
e.printStackTrace()
}
return copy
}
}
public class Main {
public static void main(String[] args) {
MyClass dh = new MyClass(100.00)
MyClass dhClone = (MyClass) dh.clone()
System.out.println("Original:" + dh.getValue())
System.out.println("Clone :" + dhClone.getValue())
dh.setValue(100.00)
dhClone.setValue(200.00)
System.out.println("Original:" + dh.getValue())
System.out.println("Clone :" + dhClone.getValue())
}
}
上面的代码生成以下结果。
Original:100.0
Clone :100.0
Original:100.0
Clone :200.0
实例-2
以下代码不从clone()
方法返回对象类型,该方法仅在Java5或更高版本中编译。
class MyClass implements Cloneable {
public MyClass clone() {
Object copy = null
return (MyClass)copy
}
}
下面的代码展示了如何做浅克隆。
class MyClass implements Cloneable {
private double value
public MyClass(double value) {
this.value = value
}
public void setValue(double value) {
this.value = value
}
public double getValue() {
return this.value
}
public Object clone() {
MyClass copy = null
try {
copy = (MyClass) super.clone()
} catch (CloneNotSupportedException e) {
e.printStackTrace()
}
return copy
}
}
class ShallowClone implements Cloneable {
private MyClass holder = new MyClass(0.0)
public ShallowClone(double value) {
this.holder.setValue(value)
}
public void setValue(double value) {
this.holder.setValue(value)
}
public double getValue() {
return this.holder.getValue()
}
public Object clone() {
ShallowClone copy = null
try {
copy = (ShallowClone) super.clone()
} catch (CloneNotSupportedException e) {
e.printStackTrace()
}
return copy
}
}
public class Main {
public static void main(String[] args) {
ShallowClone sc = new ShallowClone(100.00)
ShallowClone scClone = (ShallowClone) sc.clone()
System.out.println("Original:" + sc.getValue())
System.out.println("Clone :" + scClone.getValue())
sc.setValue(200.00)
System.out.println("Original:" + sc.getValue())
System.out.println("Clone :" + scClone.getValue())
}
}
上面的代码生成以下结果。
Original:100.0
Clone :100.0
Original:200.0
Clone :200.0
实例-3
ShallowClone
类的clone()
方法中的代码与MyClass
类的clone()
方法相同。当ShallowClone
类使用super.clone()
调用Object
类的clone()
方法时,它会接收自身的浅拷贝。也就是说,它与其克隆共享其实例变量中使用的DoubleHolder
对象。
在深克隆中,需要克隆对象的所有引用实例变量。
class MyClass implements Cloneable {
private double value
public MyClass(double value) {
this.value = value
}
public void setValue(double value) {
this.value = value
}
public double getValue() {
return this.value
}
public Object clone() {
MyClass copy = null
try {
copy = (MyClass) super.clone()
} catch (CloneNotSupportedException e) {
e.printStackTrace()
}
return copy
}
}
class DeepClone implements Cloneable {
private MyClass holder = new MyClass(0.0)
public DeepClone(double value) {
this.holder.setValue(value)
}
public void setValue(double value) {
this.holder.setValue(value)
}
public double getValue() {
return this.holder.getValue()
}
public Object clone() {
DeepClone copy = null
try {
copy = (DeepClone) super.clone()
copy.holder = (MyClass) this.holder.clone()
} catch (CloneNotSupportedException e) {
e.printStackTrace()
}
return copy
}
}
public class Main {
public static void main(String[] args) {
DeepClone sc = new DeepClone(100.00)
DeepClone scClone = (DeepClone) sc.clone()
System.out.println("Original:" + sc.getValue())
System.out.println("Clone :" + scClone.getValue())
sc.setValue(200.00)
System.out.println("Original:" + sc.getValue())
System.out.println("Clone :" + scClone.getValue())
}
}
执行上面的代码,将生成以下结果 -
Original:100.0
Clone :100.0
Original:200.0
Clone :100.0