实例分析Java浅克隆与深克隆

浅克隆:不会克隆对象中的引用类型属性,仅仅会把引用地址拷贝过来(也就是两者引用类型属性指向同一个地址)

深克隆:会克隆对象中的所有信息,原对象不会对新对象产生任何影响

浅克隆

测试:

Address类:作为Person类的一个属性

Person类:name属性、age属性、Address属性

测试类:测试深克隆与浅克隆

创建实体类

先创建一个地址类,只有城市一个属性

public class Address {
    private String city;

    public Address() {
    }

    public Address(String city) {
        this.city = city;
    }

    public String getCity() {
        return city;
    }

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

    @Override
    public String toString() {
        return "Address{" +
                "city='" + city + '\'' +
                '}';
    }
}

创建人类,实现 Cloneable 接口,并重写 clone() 方法

将地址类Address也作为人类的一个属性

public class Person implements Cloneable{
    private String name;
    private int age;
    private Address address;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    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 Address getAddress() {
        return address;
    }

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

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

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

主方法测试

public class CloneTest {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1 = new Person("机器人", 3);
        Address address = new Address("北京");
        person1.setAddress(address);

        // 克隆
        Person person2 = (Person) person1.clone();

        // 打印对象信息,及其hashCode
        System.out.println("person1: " + person1);
        System.out.println("person2: " + person2);
        System.out.println("person1 hashCode: " + person1.hashCode());
        System.out.println("person2 hashCode: " +person2.hashCode());

        System.out.println("-------------------------------------");

        // 打印对象中地址对象的信息,及其hashCode
        System.out.println("person1 address: " + person1.getAddress());
        System.out.println("person2 address: " + person2.getAddress());
        System.out.println("person1 address hashCode: " + person1.getAddress().hashCode());
        System.out.println("person2 address hashCode: " + person2.getAddress().hashCode());
    }
}

结果

person1: Person{name='机器人', age=3, address=Address{city='北京'}}
person2: Person{name='机器人', age=3, address=Address{city='北京'}}
person1 hashCode: 1625635731
person2 hashCode: 1580066828
-------------------------------------
person1 address: Address{city='北京'}
person2 address: Address{city='北京'}
person1 address hashCode: 491044090
person2 address hashCode: 491044090

两个对象的值一样,因为是克隆过来的

两个对象的hashCode不一样,因为克隆之后是两个对象,所以hashCode不一样

两个对象中的对象属性address的值相同、hashCode相同,说明address不是克隆过来的

  • 如果两个属性对象克隆成功,那么它们应该是两个对象,hashCode应该是不同的
  • 而此时两者的hashCode相同,说明此属性对象并不是克隆过来的,person2中的address属性其实还是person1中的属性

在这里插入图片描述

注:此图只助于理解

以上实现的就是浅克隆,如果将一个对象中的属性对象也克隆过来,就是深克隆

那么如何实现深克隆?

深克隆

实现person的克隆需要实现Cloneable接口并重写clone()方法,那么再实现person中的address对象属性的克隆也是类似

实现Cloneable接口并重写clone()方法

public class Address implements Cloneable{
    
    // ......
    
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

重写Person中的clone()方法

@Override
public Object clone() throws CloneNotSupportedException {
    // 实现浅克隆
    Person person = (Person) super.clone();
    // 实现深克隆
    person.setAddress((Address) address.clone());
    return person;
}

再次运行

person1: Person{name='机器人', age=3, address=Address{city='北京'}}
person2: Person{name='机器人', age=3, address=Address{city='北京'}}
person1 hashCode: 1625635731
person2 hashCode: 1580066828
-------------------------------------
person1 address: Address{city='北京'}
person2 address: Address{city='北京'}
person1 address hashCode: 491044090
person2 address hashCode: 644117698

此时person中的两个对象属性的hashCode已经不一样了,因为它也被克隆过来了,所以是两个对象,hashCode自然不同
在这里插入图片描述

注:此图只助于理解

以上就完成了对象的深克隆

此时person中的两个对象属性的hashCode已经不一样了,因为它也被克隆过来了,所以是两个对象,hashCode自然不同

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值