场景描述
把一个对象的所有成员属性拷贝给另一个对象
Java 中的数据类型分为基本数据类型和引用数据类型。对于这两种数据类型,在进行赋值操作、用作方法参数或返回值时,会有值传递和引用(地址)传递的差别。
拷贝分类
浅拷贝: Shallow Copy
深拷贝: Deep Copy
浅拷贝 Object.clone()
《介绍》会创建一个新对象。其属性值有原始对象属性值的一份精确拷贝。
(1)对于基本数据类型,基本数据类型因为是值传递,所有直接将属性值赋值给新对象。并且修改一个对象中的基本类型属性值不影响另外一个对象。
(2)对于引用数据类型,引用数据类型因为是引用传递,所以浅拷贝只是把内存地址赋值给了成员变量,改变其中一个会影响另外一个对象。
深拷贝
《介绍》实现对象拷贝的类需要实现 Cloneable 接口,并重写 clone() 方法。
(1)对于基本数据类型的成员对象,直接将属性值赋值给新的对象。和浅拷贝一样。
(2)对于引用数据类型(对象和数组)会新建一个对象空间,然后拷贝里面的内容。由于指向了新的内存地址,所以改变一个不会影响另外一个。
(3)对于有多层对象的,每个对象都需要实现 Cloneable 并重写 clone() 方法。
序列化对象(实现 Serializable )深拷贝的另一种实现方式。
必须先创建一个OutputStream,然后把它嵌入ObjectOutputStream。这时就能用writeObject()方法把对象写入OutputStream。读的时候需要把InputStream嵌到ObjectInputStream中,然后再调用readObject()方法。不过这样读出来的只是一个Object的reference,因此,在用之前,还要下转型。
// 将对象写到流里
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream oo = new ObjectOutputStream(bo);
oo.writeObject(this);
// 从流里读出来
ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
ObjectInputStream oi = new ObjectInputStream(bi);
return (oi.readObject());
**克隆一个对象与new一个对象的区别**
(1)java中clone和new都可以创建一个新的对象
(2)clone()不会调用构造方法,而new一个对象会调用类的构造方法
(3)clone()能快速创建一个已有对象的副本,即创建对象并且将已有对象中所有属性值克隆;new只能在JVM中申请一个空的内存区域,对象的属性值要通过构造方法赋值。
(4)new操作时,会先去看new操作符后面的数据类型,因为知道了类型,才知道要分配多少内存。
分配完内存后,再去调用构造函数,填充对象的各个域,这一步叫做对象的初始化,构造函数返回后,一个对象构造完成