假克隆,浅克隆,深克隆

假克隆

我觉得就是一个引用操作,不过注意引用类型的参数在源对象被改变后,假克隆的对象也会被改变

 

浅克隆

这个需要注意的是 浅克隆 对基本数据类型和不可变类对象的是可以进行的,但是是可变的引用类型需要使用深克隆

首先类需要实现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对象克隆会怎样呢?

地址信息克隆失败,直接引用过去了。

 

还有一个问题,使用序列化也可以实现"克隆",就是将 克隆的类序列化 ,然后将其保存到硬盘,再从硬盘中读取出来存到一个新的对象当中去。

不过效率低于克隆

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