• java -- 深拷贝和浅拷贝的区别 & 如何实现深拷贝和浅拷贝


    java -- 深拷贝和浅拷贝的区别 & 如何实现深拷贝和浅拷贝

    一、 深拷贝和浅拷贝的区别

    浅拷贝:对基本数据类型进行值传递,对引用数据类型进行引用传递般的拷贝,此为浅拷贝。
    深拷贝:对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容,此为深拷贝。

    • 深拷贝和浅拷贝最根本的区别在于是否真正获取一个对象的复制实体,而不是引用。
      在这里插入图片描述
    假设B复制了A,修改A的时候,看B是否发生变化:
    如果B跟着也变了,说明是浅拷贝(修改堆内存中的同一个值)
    如果B没有改变,说明是深拷贝(修改堆内存中的不同的值)
    
    • 1
    • 2
    • 3

    浅拷贝(shallowCopy) 只是增加了一个指针指向已存在的内存地址,
    深拷贝(deepCopy) 是增加了一个指针并且申请了一个新的内存,使这个增加的指针指向这个新的内存。
    深拷贝是指源对象与拷贝对象互相独立,其中任何一个对象的改动都不会对另外一个对象造成影响。
    使用深拷贝的情况下,释放内存的时候不会因为出现浅拷贝时释放同一个内存的错误。

    二、重载clone()方法

    Object类有个clone()的拷贝方法,不过它是protected类型的,我们需要重写它并修改为public类型。除此之外,子类还需要实现Cloneable接口来告诉JVM这个类是可以拷贝的。

    让我们修改一下Fruit类,实现Cloneable接口,使其支持深拷贝。

    public class Fruit implements Cloneable {
    
        private String name;
    
        private String color;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getColor() {
            return color;
        }
    
        public void setColor(String color) {
            this.color = color;
        }
    
        @Override
        public String toString() {
            return "Fruit{" +
                    "name='" + name + '\'' +
                    ", color='" + color + '\'' +
                    '}';
        }
    
        @Override
        public Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    public class cloneTest {
    
        public static void main(String[] args) {
            Fruit fruit = new Fruit();
            fruit.setName("香蕉");
            fruit.setColor("黄色");
            Fruit fruit2 = fruit;
            Fruit fruitClone = null;
            try {
                fruitClone = (Fruit) fruit.clone();
                fruit.setName("西瓜");
                fruit.setColor("绿色");
                System.out.println("深拷贝-----》 " + fruitClone + "\t 是否同一对象" + (fruitClone == fruit));
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            System.out.println("浅拷贝-----》 " + fruit2 + "\t 是否同一对象" + (fruit2 == fruit));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    深拷贝-----Fruit{name='香蕉', color='黄色'}	 是否同一对象false
    浅拷贝-----Fruit{name='西瓜', color='绿色'}	 是否同一对象true
    
    
    • 1
    • 2
    • 3
  • 相关阅读:
    养生与健康|一起跟随林曦老师养个元气满满
    瑞芯微RV1126/1109开发流程之MPP部署
    【设计模式】原型模式
    Linux开机自动执行某些命令运行自定义脚本的方法
    【利用Selenium+autoIt实现文件上传】
    2024中国商业医疗险发展研究蓝皮书
    Vue---v-for渲染和样式绑定
    国内表格软件-FineReport Count函数
    邮件注册(一)验证码发送
    TCP三次握手具体过程
  • 原文地址:https://blog.csdn.net/qq_43070052/article/details/132725663