【Java深拷贝与浅拷贝 深克隆与浅克隆】

深拷贝与浅拷贝

浅拷贝

public class Address {
    private String city;
    public Address() {
    }
    public String getCity() {
        return city;
    }
    public void setCity(String city) {
        this.city = city;
    }
    public Address(String city) {
        this.city = city;
    }
}
public class Person implements Cloneable{
    private String nickname;
    private Address address;

    public String getNickname() {
        return nickname;
    }
    public void setNickname(String nickname) {
        this.nickname = nickname;
    }
    public Address getAddress() {
        return address;
    }
    public void setAddress(Address address) {
        this.address = address;
    }
    public Person() {
    }
    public Person(String nickname, Address address) {
        this.nickname = nickname;
        this.address = address;
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        // 默认浅拷贝
 		return super.clone();
    }
}
public class PersonTest {
    @Test
    public void test03()throws CloneNotSupportedException{
        Person person = new Person("张三",new Address("上海"));
        System.out.println(person.getAddress().getCity());
        // clone的返回值类型是Object类型 需要向下转型
        Person clone = (Person) person.clone();
        System.out.println(clone.getAddress().getCity());
        person.setNickname("李四");
        person.getAddress().setCity("北京");
        System.out.println(person.getNickname());
        System.out.println(person.getAddress().getCity());
        System.out.println(clone.getNickname());
        System.out.println(clone.getAddress().getCity());
    }
}

输出

上海
上海
李四
北京
张三
北京

深拷贝

方式一:

public class Address implements Cloneable{
    private String city;
    public Address() {
    }
    public String getCity() {
        return city;
    }
    public void setCity(String city) {
        this.city = city;
    }
    public Address(String city) {
        this.city = city;
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
public class Person implements Cloneable{
    private String nickname;
    private Address address;
    public Person(String nickname, String city) {
    }
    public String getNickname() {
        return nickname;
    }
    public void setNickname(String nickname) {
        this.nickname = nickname;
    }
    public Address getAddress() {
        return address;
    }
    public void setAddress(Address address) {
        this.address = address;
    }
    public Person() {
    }

    public Person(String nickname, Address address) {
        this.nickname = nickname;
        this.address = address;
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        // 默认浅拷贝
        // return super.clone();
        // 深拷贝
        // 一种是在Address克隆一次 另一种如下:
        //return new Person(this.nickname,new Address(this.getAddress().getCity()));
        return new Person(this.nickname, (Address) this.getAddress().clone());
    }
}
public class PersonTest {
    @Test
    public void test03()throws CloneNotSupportedException{
        Person person = new Person("张三",new Address("上海"));
        System.out.println(person.getAddress().getCity());
        // clone的返回值类型是Object类型 需要向下转型
        Person clone = (Person) person.clone();
        System.out.println(clone.getAddress().getCity());
        person.setNickname("李四");
        person.getAddress().setCity("北京");
        System.out.println(person.getNickname());
        System.out.println(person.getAddress().getCity());
        System.out.println(clone.getNickname());
        System.out.println(clone.getAddress().getCity());
    }
}

输出

上海
上海
李四
北京
张三
上海

方式二:

public class Address{
    private String city;

    public Address() {
    }
    public String getCity() {
        return city;
    }
    public void setCity(String city) {
        this.city = city;
    }
    public Address(String city) {
        this.city = city;
    }
}
public class Person implements Cloneable{
    private String nickname;
    private Address address;
    public Person(String nickname, String city) {
    }
    public String getNickname() {
        return nickname;
    }
    public void setNickname(String nickname) {
        this.nickname = nickname;
    }
    public Address getAddress() {
        return address;
    }
    public void setAddress(Address address) {
        this.address = address;
    }
    public Person() {
    }
    public Person(String nickname, Address address) {
        this.nickname = nickname;
        this.address = address;
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        // 默认浅拷贝
        // return super.clone();
        // 深拷贝
        // 一种是在Address克隆一次 另一种如下:
        return new Person(this.nickname,new Address(this.getAddress().getCity()));
        //return new Person(this.nickname, (Address) this.getAddress().clone());
    }
}
public class PersonTest {
    @Test
    public void test03()throws CloneNotSupportedException{
        Person person = new Person("张三",new Address("上海"));
        System.out.println(person.getAddress().getCity());
        // clone的返回值类型是Object类型 需要向下转型
        Person clone = (Person) person.clone();
        System.out.println(clone.getAddress().getCity());
        person.setNickname("李四");
        person.getAddress().setCity("北京");
        System.out.println(person.getNickname());
        System.out.println(person.getAddress().getCity());
        System.out.println(clone.getNickname());
        System.out.println(clone.getAddress().getCity());
    }
}

输出

上海
上海
李四
北京
张三
上海

深克隆与浅克隆

浅克隆(Shallow clone)

浅客隆是指拷贝对象时仅仅copy对象本身和对象中的基本变量,而不拷贝对象包含的引用指向的对象

public class Address implements Cloneable{
    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
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
public class PersonShallow implements Cloneable{
    private String nickname;
    private Address address;
    public PersonShallow() {
    }
    public PersonShallow(String nickname, Address address) {
        this.nickname = nickname;
        this.address = address;
    }
    public String getNickname() {
        return nickname;
    }
    public void setNickname(String nickname) {
        this.nickname = nickname;
    }
    public Address getAddress() {
        return address;
    }
    public void setAddress(Address address) {
        this.address = address;
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
    public static void main(String[] args) {
        Address address = new Address("上海");
        PersonShallow person = new PersonShallow("张三",address);
        try{
            PersonShallow clone = (PersonShallow) person.clone();
            System.out.println(person==clone);
            System.out.println(person.getClass()==clone.getClass());
            System.out.println(person.getAddress()==clone.getAddress());
            System.out.println(person.getAddress().getClass()==clone.getAddress().getClass());
        }catch (CloneNotSupportedException e){
            e.printStackTrace();
        }
    }
}

输出

false
true
true
true

深克隆(deep clone)

不仅copy对象本身,而且copy对象包含的引用指向的所有对象

public class Address implements Cloneable{
    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
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
public class PersonDeep implements Cloneable{
    private String nickname;
    private Address address;
    public PersonDeep() {
    }
    public PersonDeep(String nickname, Address address) {
        this.nickname = nickname;
        this.address = address;
    }
    public String getNickname() {
        return nickname;
    }
    public void setNickname(String nickname) {
        this.nickname = nickname;
    }
    public Address getAddress() {
        return address;
    }
    public void setAddress(Address address) {
        this.address = address;
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        PersonDeep personDeep = (PersonDeep)super.clone();
        Address address = (Address)personDeep.getAddress().clone();
        personDeep.setAddress(address);
        return personDeep;
    }
    public static void main(String[] args) {
        Address address = new Address("上海");
        PersonDeep person = new PersonDeep("张三",address);
        try{
            PersonDeep clone = (PersonDeep) person.clone();
            System.out.println(person==clone);
            System.out.println(person.getClass()==clone.getClass());
            System.out.println(person.getAddress()==clone.getAddress());
            System.out.println(person.getAddress().getClass()==clone.getAddress().getClass());
        }catch (CloneNotSupportedException e){
            e.printStackTrace();
        }
    }
}

输出

false
true
false
true

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Rita_zzf

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值