专业的JAVA编程教程与资源

网站首页 > java教程 正文

阿瑟Java (25):如何拷贝一个对象?(深拷贝和浅拷贝)

temp10 2024-10-19 14:54:58 java教程 14 ℃ 0 评论

PS:创作不易,感谢阅读,希望对读者有所帮助,喜欢的话可以点赞、收藏、关注,作者会持续更新 Java 生态圈常见知识。黑色加粗为重点关注内容!

基本概述

  • 主要考察基本类型、引用类型的理解深度。
  • 基本数据类型和引用数据类型
    • 基本数据类型:就是值类型,内存中存储的是值。
    • 引用数据类型:就是地址类型
  • 基本变量和引用变量存储示例
    • age 是局部变量,所以在栈中申请内存空间,又由于 age 的值是基本类型,所以值直接存储在栈中。
    • arr 是局部变量,所以在栈中申请空间,但是由于 arr 值不是基本类型,而是引用类型(new出来的),所以,先在堆中申请空间存放数据 12,23,34,。再把堆区的地址赋给arr。

浅拷贝

  • 基本数据类型:
    • 是值传递,直接将属性值赋值给新的对象。
    • 基础类型的拷贝,其中一个对象修改值,不会影响另外一个
  • 引用数据类型:
    • 是引用传递,所以浅拷贝只是把内存地址赋值给了新对象,它们指向了同一内存空间
    • 改变其中一个,会对另外一个也产生影响
  • 实现对象拷贝的类,需要实现 Cloneable 接口,并覆写 clone() 方法。
public class Subject {
    private String name;
    ......
}
public class Student implements Cloneable {
    //引用类型
    private Subject subject;
    //基础数据类型
    private String name;
    private int age;
    
    /**
     *  重写clone()方法
     * @return
     */
    @Override
    public Object clone() {
        //浅拷贝
        try {
            // 直接调用父类的clone()方法,此时subject局部变量只是拷贝了引用地址
            return super.clone();
        } catch (CloneNotSupportedException e) {
            return null;
        }
    }
}

深拷贝

  • 基本数据类型:
    • 是值传递的,直接将属性值赋值给新的对象。
    • 基础类型的拷贝,其中一个对象修改值,不会影响另外一个
  • 引用数据类型:
    • 深拷贝会新建一个对象空间,然后拷贝里面的内容,所以它们指向了不同的内存空间
    • 改变其中一个,不会对另外一个也产生影响
  • 对于有多层对象的,每个对象都需要实现 Cloneable 并重写 clone() 方法,进而实现了对象的串行层层拷贝。
public class Subject {
    private String name;
    ......
    @Override
protected Object clone() throws CloneNotSupportedException 	  {
        //Subject 如果也有引用类型的成员属性,也应该和 Student 类一样实现
        return super.clone();
    }
}
public class Student implements Cloneable {
    //引用类型
    private Subject subject;
    //基础数据类型
    private String name;
    private int age;
    
    /**
     *  重写clone()方法
     * @return
     */
    @Override
    public Object clone() {
        //深拷贝
        try {
            // 直接调用父类的clone()方法
            Student student = (Student) super.clone();
            student.subject = (Subject) subject.clone();
            return student;
        } catch (CloneNotSupportedException e) {
            return null;
        }
    }
}

深拷贝-序列化

  • 基于序列化和反序列化实现的克隆不仅仅是深度克隆
  • 更重要的是通过泛型限定,可以检查出要克隆的对象是否支持序列化,这项检查是编译器完成的,不是在运行时抛出异常,这种是方案明显优于使用 Object 类的 clone 方法克隆对象。

阿瑟Java (25):如何拷贝一个对象?(深拷贝和浅拷贝)

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表