Object类中clone()方法

  1. 使用场景
    当我们需要创建一个对象的副本的时候,并且在改变他们各自的内容的时候互不影响,就可以使用Object类中clone()方法
  2. 使用clone()方法需要注意
    需要实现Cloneable接口,否则抛出CloneNotSupportedException
    需要调用super.clone()
    该方法实现"浅拷贝"而不是“深拷贝”
  3. “浅拷贝”和“深拷贝”的区别
    浅拷贝:被拷贝的对象中不含有其他实体类对象的引用
    深拷贝:被拷贝对象中含有其他实体类对象的引用,那么这些实体类都需要实现Cloneable接口,实现clone()方法

浅拷贝

/**
 * @Author: 保质期已过
 * @Date: 2020/6/3 22:28
 * Description:
 * @Version 1.0
 */
@Data
@AllArgsConstructor(access = AccessLevel.PUBLIC)
public class Address{

    private String addressName;

}
@Data
@AllArgsConstructor(access=AccessLevel.PUBLIC)
public class Person implements Cloneable {

    private String name;

    private int age;

    //引用类型对象
    private Address address;

    //浅复制
    public Person clone() throws CloneNotSupportedException {
        return (Person)super.clone();
    }

}

测试浅拷贝

@org.junit.jupiter.api.Test
    public static void test01() throws CloneNotSupportedException {
        Address address = new Address("成都");
        Person person = new Person("张三",20,address);
        Person person1 = person.clone();
        System.out.println(person1.toString());
    }

输出
Person(name=张三, age=20, address=Address(addressName=成都))

4.实体类对象拷贝问题
我们看到Address实体类对象的引用,也被复制过来了,其实这里只是复制了引用,并没有创建Address新的副本。执行如下测试代码,但我们在修改拷贝后person对象的Address中的addressName属性值时,拷贝前的person中的Address中的addressName属性值也被更改了

@org.junit.jupiter.api.Test
    public void test02() throws CloneNotSupportedException {
        Address address = new Address("成都");
        Person person = new Person("张三",20,address);
        Person person1 = person.clone();
        person1.getAddress().setAddressName("武漢");
        System.out.println("拷贝后的person:"+person1.toString());
        System.out.println("拷贝前的person:"+person.toString());
    }

输出
拷贝后的person:Person(name=张三, age=20, address=Address(addressName=成都))
拷贝前的person:Person(name=张三, age=20, address=Address(addressName=武漢))

深拷贝

改造Address类,也实现Cloneable接口,重写clone()方法

/**
 * @Author: 保质期已过
 * @Date: 2020/6/3 22:28
 * Description:
 * @Version 1.0
 */
@Data
@AllArgsConstructor(access = AccessLevel.PUBLIC)
public class Address implements Cloneable{

    private String addressName;

    public Address clone() throws CloneNotSupportedException {
        return (Address) super.clone();
    }
}

改造Person类,新增深拷贝的方法

/**
 * @Author: 保质期已过
 * @Date: 2020/6/3 21:45
 * Description:
 * @Version 1.0
 */
@Data
@AllArgsConstructor(access=AccessLevel.PUBLIC)
public class Person implements Cloneable {

    private String name;

    private int age;

    //引用类型对象
    private Address address;

    //浅拷贝
    public Person clone() throws CloneNotSupportedException {
        return (Person)super.clone();
    }

    //深拷贝
    public Person deepClone() throws CloneNotSupportedException {
        Person person = (Person) super.clone();
        Address newaddress = (Address) address.clone();
        person.address = (Address) address.clone();
        return person;
    }
}

测试深拷贝

@org.junit.jupiter.api.Test
    public void test03() throws CloneNotSupportedException {
        Address address = new Address("成都");
        Person person = new Person("张三",20,address);
        Person person1 = person.deepClone();
        person1.getAddress().setAddressName("武漢");
        System.out.println("拷贝后的person:"+person1.toString());
        System.out.println("拷贝前的person:"+person.toString());
    }

输出
拷贝后的person:Person(name=张三, age=20, address=Address(addressName=武漢))
拷贝前的person:Person(name=张三, age=20, address=Address(addressName=成都))

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值