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
上一篇:
Java对象toString()方法
下一篇:
Java对象finalize()方法