作者:小P美容2000 | 来源:互联网 | 2023-09-18 13:25
对象拷贝
61. 为什么要使用克隆?
想对一个对象进行处理,又想保留原有的数据进行接下来的操作,就需要克隆了,Java语言中克隆针对的是类的实例。
62. 如何实现对象克隆?
有两种方式:
实现Cloneable接口并重写Object类中的clone()方法;
实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆,代码如下:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;public class MyUtil {private MyUtil() {throw new AssertionError();}&#64;SuppressWarnings("unchecked")public static <T extends Serializable> T clone(T obj) throws Exception {ByteArrayOutputStream bout &#61; new ByteArrayOutputStream();ObjectOutputStream oos &#61; new ObjectOutputStream(bout);oos.writeObject(obj);ByteArrayInputStream bin &#61; new ByteArrayInputStream(bout.toByteArray());ObjectInputStream ois &#61; new ObjectInputStream(bin);return (T) ois.readObject();}
}
下面是测试代码&#xff1a;
import java.io.Serializable;
class Person implements Serializable {private static final long serialVersionUID &#61; -9102017020286042305L;private String name; private int age; private Car car; public Person(String name, int age, Car car) {this.name &#61; name;this.age &#61; age;this.car &#61; car;}public String getName() {return name;}public void setName(String name) {this.name &#61; name;}public int getAge() {return age;}public void setAge(int age) {this.age &#61; age;}public Car getCar() {return car;}public void setCar(Car car) {this.car &#61; car;}&#64;Overridepublic String toString() {return "Person [name&#61;" &#43; name &#43; ", age&#61;" &#43; age &#43; ", car&#61;" &#43; car &#43; "]";}}
class Car implements Serializable {private static final long serialVersionUID &#61; -5713945027627603702L;private String brand; private int maxSpeed; public Car(String brand, int maxSpeed) {this.brand &#61; brand;this.maxSpeed &#61; maxSpeed;}public String getBrand() {return brand;}public void setBrand(String brand) {this.brand &#61; brand;}public int getMaxSpeed() {return maxSpeed;}public void setMaxSpeed(int maxSpeed) {this.maxSpeed &#61; maxSpeed;}&#64;Overridepublic String toString() {return "Car [brand&#61;" &#43; brand &#43; ", maxSpeed&#61;" &#43; maxSpeed &#43; "]";}}
class CloneTest {public static void main(String[] args) {try {Person p1 &#61; new Person("郭靖", 33, new Car("Benz", 300));Person p2 &#61; MyUtil.clone(p1); p2.getCar().setBrand("BYD");System.out.println(p1);} catch (Exception e) {e.printStackTrace();}}
}
注意&#xff1a;基于序列化和反序列化实现的克隆不仅仅是深度克隆&#xff0c;更重要的是通过泛型限定&#xff0c;可以检查出要克隆的对象是否支持序列化&#xff0c;这项检查是编译器完成的&#xff0c;不是在运行时抛出异常&#xff0c;这种是方案明显优于使用Object类的clone方法克隆对象。让问题在编译的时候暴露出来总是好过把问题留到运行时。
63. 深拷贝和浅拷贝区别是什么&#xff1f;
浅拷贝只是复制了对象的引用地址&#xff0c;两个对象指向同一个内存地址&#xff0c;所以修改其中任意的值&#xff0c;另一个值都会随之变化&#xff0c;这就是浅拷贝&#xff08;例&#xff1a;assign()&#xff09;
深拷贝是将对象及值复制过来&#xff0c;两个对象修改其中任意的值另一个值不会改变&#xff0c;这就是深拷贝&#xff08;例&#xff1a;JSON.parse()和JSON.stringify()&#xff0c;但是此方法无法复制函数类型&#xff09;
原文地址&#xff1a;https://mp.weixin.qq.com/s/0KM4e3_zPczHh2TH2r_ncA