假克隆,淺克隆,深克隆

假克隆

我覺得就是一個引用操作,不過注意引用類型的參數在源對象被改變後,假克隆的對象也會被改變

 

淺克隆

這個需要注意的是 淺克隆 對基本數據類型和不可變類對象的是可以進行的,但是是可變的引用類型需要使用深克隆

首先類需要實現Cloneable接口

並且要實現clone方法 需要重寫父類的clone方法

因爲父類的protocol類型修飾 如果要在其他包使用 需要改成public類型

整個淺克隆的類代碼如下:

package method;

import java.util.Objects;


public class OverrideHash implements Cloneable {

    private int id;
    private String name;
    private int age;
    private int gender;

    public OverrideHash() {
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getGender() {
        return gender;
    }

    public void setGender(int gender) {
        this.gender = gender;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        OverrideHash that = (OverrideHash) o;
        return id == that.id &&
                age == that.age &&
                gender == that.gender &&
                Objects.equals(name, that.name);
    }

    @Override
    public int hashCode() {

        return Objects.hash(id, name, age, gender);
    }

    @Override
    public OverrideHash clone() {
        OverrideHash overrideHash = null;

        try {
            overrideHash = (OverrideHash) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }

        return overrideHash;
    }

    @Override
    public String toString() {
        return "OverrideHash{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", gender=" + gender +
                '}';
    }
}

這裏可以和假克隆一起做個栗子 比較下

最後得到結論是:

很明顯看到在兩個克隆對象後面修改了原對象的一個參數,假克隆的對應參數被修改了,而淺克隆的沒有。

 

深克隆:

深克隆的條件時如果需要克隆的對象的參數中包括了可變引用類型,則在克隆時使用深克隆

直接舉個栗子:

一個只有基本數據類型和不可變的引用類型  address類

public class Address implements Cloneable {

    private int id;
    private String contry;
    private String province;
    private String city;
    private String street;

    public Address(int id, String contry, String province, String city, String street) {
        this.id = id;
        this.contry = contry;
        this.province = province;
        this.city = city;
        this.street = street;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getContry() {
        return contry;
    }

    public void setContry(String contry) {
        this.contry = contry;
    }

    public String getProvince() {
        return province;
    }

    public void setProvince(String province) {
        this.province = province;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Address address = (Address) o;
        return id == address.id &&
                Objects.equals(contry, address.contry) &&
                Objects.equals(province, address.province) &&
                Objects.equals(city, address.city) &&
                Objects.equals(street, address.street);
    }

    @Override
    public int hashCode() {

        return Objects.hash(id, contry, province, city, street);
    }

    @Override
    public Object clone() {
        Address address = null;
        try {
            address = (Address) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return address;
    }

    @Override
    public String toString() {
        return "Address{" +
                "id=" + id +
                ", contry='" + contry + '\'' +
                ", province='" + province + '\'' +
                ", city='" + city + '\'' +
                ", street='" + street + '\'' +
                '}';
    }
}

再來個user對象,用於深克隆

public class User implements Cloneable {

    private int id;

    private String name;

    private int age;

    private int gender;

    private Address address;

    public User(int id, String name, int age, int gender, Address address) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.gender = gender;
        this.address = address;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getGender() {
        return gender;
    }

    public void setGender(int gender) {
        this.gender = gender;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return id == user.id &&
                age == user.age &&
                gender == user.gender &&
                Objects.equals(name, user.name) &&
                Objects.equals(address, user.address);
    }

    @Override
    public int hashCode() {

        return Objects.hash(id, name, age, gender, address);
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", gender=" + gender +
                ", address=" + address.toString() +
                '}';
    }

    @Override
    public Object clone() {
        User user = null;
        try {
            user = (User) super.clone();
            user.address = (Address) address.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return user;
    }
}

注意得到的是 user在克隆的時候將Address對象單獨進行了一次克隆。

這樣才能保證address對象的參數克隆過去

舉個栗子嘗試下:

得到的結果:

引用對象也克隆成功了

如果 不將Address對象克隆會怎樣呢?

地址信息克隆失敗,直接引用過去了。

 

還有一個問題,使用序列化也可以實現"克隆",就是將 克隆的類序列化 ,然後將其保存到硬盤,再從硬盤中讀取出來存到一個新的對象當中去。

不過效率低於克隆

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