https://blog.csdn.net/qq_37174526/article/details/86484517
https://blog.csdn.net/forwujinwei/article/details/79915872
我們經常會用到對象的拷貝,但是但是繼承Cloneable重寫clone實現的只是淺拷貝,那麼什麼是深拷貝,什麼是淺拷貝呢。
拷貝就是設計模式中原型模式的一種體現,原型模式是內存二進制流的拷貝,要比new一個對象的性能好的多的多,特別是在for循環中產生大量對象時,原型模式能更好的體現其優點。
其實從內存方面來說簡單一句話,就是看有沒有開闢新的內存空間用於存儲拷貝的對象,淺拷貝只是拷貝一份引用,而深拷貝重新開闢堆內存存儲拷貝的數據,淺拷貝對於基本類型和字符串String類型有效,具體原因這裏不展開
java中實現深拷貝的兩種方式
-
clone() 方法麻煩一些,需要將所有涉及到的類實現聲明式接口 Cloneable,並覆蓋Object類中的clone()方法,並設置作用域爲public(這是爲了其他類可以使用到該clone方法)。
-
序列化的方法簡單,需要將所有涉及到的類實現接口Serializable
一、重寫clone方法
class Car implements Cloneable, Serializable {
private String band;
public Car(String band) {
this.band = band;
}
public String getBand() {
return band;
}
public void setBand(String band) {
this.band = band;
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Employee implements Cloneable, Serializable {
private String name;
private Car car;
public Employee(String name, Car car) {
this.name = name;
this.car = car;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Car getcar() {
return car;
}
public void setcar(Car car) {
this.car = car;
}
protected void test() {
System.out.println("test func");
}
@Override
public Object clone() throws CloneNotSupportedException {
Employee employee_cloned = (Employee) super.clone();
Car car_cloned = (Car) this.car.clone();
employee_cloned.setcar(car_cloned);
return employee_cloned;
}
}
二、藉助序列化
public class SerializedClone {
@SuppressWarnings("unchecked")
public static <T extends Serializable> T clone(T obj) {
T cloneObj = null;
try {
//寫入字節流
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream obs = new ObjectOutputStream(out);
obs.writeObject(obj);
obs.close();
//分配內存,寫入原始對象,生成新對象
ByteArrayInputStream ios = new ByteArrayInputStream(out.toByteArray());
ObjectInputStream ois = new ObjectInputStream(ios);
//返回生成的新對象
cloneObj = (T) ois.readObject();
ois.close();
} catch (Exception e) {
e.printStackTrace();
}
return cloneObj;
}
}