深拷贝浅拷贝及原型模式
浅拷贝
浅拷贝是按位拷贝对象,它会创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值;如果属性是内存地址(引用类型),拷贝的就是内存地址 ,因此如果其中一个对象改变了这个地址,就会影响到另一个对象。即默认拷贝构造函数只是对对象进行浅拷贝复制(逐个成员依次拷贝),即只复制对象空间而不复制资源。
如 :
1 |
|
可以发现对于拷贝的对象,修改拷贝之前的属性,如属性是基本类型,则无影响,如属性是对象,则会影像拷贝之后的对象。所以浅拷贝会带来数据安全上的问题。
深拷贝
深拷贝,在拷贝引用类型成员变量时,为引用类型的数据成员另辟了一个独立的内存空间,实现真正内容上的拷贝。
- 对于基本数据类型的成员对象,因为基础数据类型是值传递的,所以是直接将属性值赋值给新的对象。基础类型的拷贝,其中一个对象修改该值,不会影响另外一个(和浅拷贝一样)。
- 对于引用类型,比如数组或者类对象,深拷贝会新建一个对象空间,然后拷贝里面的内容,所以它们指向了不同的内存空间。改变其中一个,不会对另外一个也产生影响。
- 对于有多层对象的,每个对象都需要实现 Cloneable 并重写 clone() 方法,进而实现了对象的串行层层拷贝。
- 深拷贝相比于浅拷贝速度较慢并且花销较大。
对上面的代码实现深拷贝
1 |
|
问题
问:Cloneable接口是一个空接口,为什么需要实现Cloneable接口?
答:Cloneable是标示接口与java.io.Serializable类似,用于告知JVM该对象实现clone。并且super.clone()可以返回一个复制。如果实现Cloneable接口直接super.clone(),会抛出CloneNotSupportedException。
原型模式
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象,从一个对象创建另外一个可定制的对象,而且不需要知道任何创建的细节。
基本代码
1 | 4j |