深克隆、浅克隆

文章详细阐述了Java中的浅克隆和深克隆概念,通过代码示例展示了如何实现。浅克隆仅复制对象的基本类型数据,引用类型的数据仍共享同一引用。深克隆不仅复制对象本身,还递归复制其引用的对象,确保修改副本不会影响原始对象。此外,文章提到序列化也可用于实现深复制的效果。
摘要由CSDN通过智能技术生成

目录

一、浅克隆

二、深克隆

三、总结


一、浅克隆

        1)什么是浅克隆?

                被Clone的对象的所有变量都含有原来对象相同的值,而引用变量还是原来对用的引用【拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),而不拷贝对象包含的引用指向的对象。】即若对象中有引用数据类型的变量则无法拷贝

public class test {
    public static void main(String[] args) {
        User user1 = new User("zs",  new People("zs", 1));
        try {
            User clone = user1.clone();
            clone.setName("ls");
            System.out.println(user1.getName().hashCode());//3897
            System.out.println(clone.getName().hashCode());//3463
            //引用类变量地址并未发生变化
            System.out.println(user1.getPeople().hashCode());//1134712904
            System.out.println(clone.getPeople().hashCode());//1134712904
            System.out.println(user1 == clone); //false
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

class User{
    private String name;
    private People people;

    public User(){}

    public User(String name, People people) {
        this.name = name;
        this.people = people;
    }

    public People getPeople() {
        return people;
    }

    public void setPeople(People people) {
        this.people = people;
    }

    @Override
    protected User clone() throws CloneNotSupportedException {
        return (User) super.clone();
    }


    public String getName() {
        return name;
    }

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

}

class People{
    String name;
    Integer no;

    public People(){}

    public People(String name, Integer no) {
        this.name = name;
        this.no = no;
    }
}
二、深克隆

        1)什么是深克隆?

                被克隆对象的所有变量都含有原来的对象相同的值,引用变量也重新复制了一份【不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象】引用数据类型的变量地址改变。

class test1 {
    public static void main(String[] args) {
        Clazz clazz1 = new Clazz(1L, "zs",  new Student(1L, "zs", 1));
        try {
            Clazz clone = clazz1.clone();
            clone.setName("ls");
            System.out.println(clazz1.getName().hashCode());//3897
            System.out.println(clone.getName().hashCode());//3463
            //引用类变量地址并发生变化
            System.out.println(clazz1.getStu().hashCode());//1956725890
            System.out.println(clone.getStu().hashCode());//356573597
            System.out.println(clazz1 == clone); //false
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}
class Student implements Cloneable{

    private Long id;
    private String name;
    private Integer sex;

    public Student() {

    }

    public Student(Long id, String name, Integer sex) {
        this.id = id;
        this.name = name;
        this.sex = sex;
    }

    @Override
    protected Student clone() throws CloneNotSupportedException {
        return (Student)super.clone();
    }


    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getSex() {
        return sex;
    }
    public void setSex(Integer sex) {
        this.sex = sex;
    }


    @Override
    public String toString() {
        return "Student [id=" + id + ", name=" + name + ", sex=" + sex + "]";
    }
}
public class Clazz implements Cloneable {


    private Long number;
    private String name;
    private Student stu;

    public Clazz() {
    }

    public Clazz(Long number, String name, Student stu) {
        this.number = number;
        this.name = name;
        this.stu = stu;
    }

    @Override
    protected Clazz clone() throws CloneNotSupportedException {
        Clazz cla = (Clazz)super.clone();
        cla.stu = stu.clone(); // 引用对象也需要Clone
        return cla;
    }

    public Long getNumber() {
        return number;
    }
    public void setNumber(Long number) {
        this.number = number;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Student getStu() {
        return stu;
    }
    public void setStu(Student stu) {
        this.stu = stu;
    }

    @Override
    public String toString() {
        return "Clazz [number=" + number + ", name=" + name + ", stu=" + stu + "]";
    }

}
三、总结
  1. 浅克隆:只复制基本类型的数据,引用类型的数据只复制了引用的地址,引用的对象并没有复制,在新的对象中修改引用类型的数据会影响原对象中的引用。
  2. 深克隆:是在引用类型的类中也实现了clone,是clone的嵌套,复制后的对象与原对象之间完全不会影响。
  3. 使用序列化也能完成深复制的功能:对象序列化后写入流中,此时也就不存在引用什么的概念了,再从流中读取,生成新的对象,新对象和原对象之间也是完全互不影响的。
  4. 使用clone实现的深克隆其实是浅克隆中嵌套了浅克隆,与toString方法类似
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值