Java 深拷贝、浅拷贝及Cloneable接口
复制是一个具有潜在危险的操作,因为它可能引起不是你所期望的副作用。例如,假如被复制的对象包含了一个称为obRef的引用变量,当副本创建时,副 本中的obRef如同原对象中的obRef一样引用相同的对象。如果副本改变了被obRef引用的对象的内容,那么对应的原对象也将被改变。这里是另一个 例子。如果一个对象打开一个I/O流并被复制,两个对象将可操作相同的流。而且,如果其中一个对象关闭了流,而另一个对象仍试图对I/O流进行写操作的 话,将导致错误。
Cloneable接口是一个空接口,仅用于标记对象,Cloneable接口里面是没有clone()方法,的clone()方法是Object类里面的方法!默认实现是一个Native方法
1
|
protected native Object clone() throws CloneNotSupportedException; |
如果对象implement Cloneable接口的话,需要覆盖clone方法(因为Object类的clone方法是protected,需要覆盖为public)
1
2
3
|
public Object clone() throws CloneNotSupportedException{ return super .clone(); } |
Object类里的clone()方法仅仅用于浅拷贝(拷贝基本成员属性,对于引用类型仅返回指向改地址的引用)
深拷贝需要重新覆盖Clone方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
public class testDeepClone implements Cloneable { public int num = 0 ; public String str = "default" ; public A a; public Object clone() throws CloneNotSupportedException { testDeepClone o = (testDeepClone) super .clone(); o.str = new String( this .str); o.a = (A) a.clone(); return o; } } // 成员属性A必须为Cloneable的,否则无法Clone其组合的类 class A implements Cloneable { public Object clone() throws CloneNotSupportedException { return super .clone(); } } |
利用Serializable来实现深层复制
利用Serializable进行深拷贝的时候成员属性也必须是Serializable的,否则只返回一个引用,具体参考本人的博客: