java中的淺拷貝、深拷貝

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;
    }

}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章