深拷贝是彻底的拷贝,两对象中所有的成员都是独立的一份,而且,成员对象中的成员对象也是独立一份。
浅拷贝中的某些成员变量可能是共享的,深拷贝如果不够彻底,就是浅拷贝。
下图就是一个彻底的深拷贝,每一个成员都有一份对应的拷贝:
而下面这个图是浅拷贝,虽然有部分成员有对应的拷贝,但是,还是有部分成员变量是共享的,所以不是一个彻底的深拷贝。通常来说,值类型在浅拷贝的时候会复制一个独立的副本,而引用类型的数据,在浅拷贝是只是拷贝了一个引用。
Object 的 clone 方法是一个浅拷贝,如果它拷贝的对象中有其他对象,那么其中的对象是不会得到彻底的拷贝。
不要试图用 Cloneable 接口实现深拷贝。
Cloneable 接口只是一个标识接口,它未定义任何 clone 方法。通常使用它,还是需要覆盖 Object 的 Clone 方法(只有实现了 Cloneable 接口才可以调用 clone 方法),这种写法很容易导致未深拷贝不够彻底。《Effective Java》对此有更详细的说明。
笔者建议通过实现一个拷贝构造函数,或者使用第三方的方法,比如 apache-commons 的 SerializationUtils 方法来实现。