首页 > 编程语言 >Java深入理解深拷贝和浅拷贝区别

Java深入理解深拷贝和浅拷贝区别

时间:2024-12-17 16:56:46浏览次数:4  
标签:Java name Teacher age teacher 深入 拷贝 public

一、拷贝的引入

(1)、引用拷贝

创建一个指向对象的引用变量的拷贝。

public class QuoteCopy {
    public static void main(String[] args) {
        Teacher teacher = new Teacher("riemann", 28);
        Teacher otherTeacher = teacher;
        System.out.println(teacher);
        System.out.println(otherTeacher);
    }
}

class Teacher {
    private String name;
    private int age;

    public Teacher(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

输出结果:

com.test.Teacher@28a418fc
com.test.Teacher@28a418fc

结果分析:由输出结果可以看出,它们的地址值是相同的,那么它们肯定是同一个对象。teacherotherTeacher只是引用而已,他们都指向了一个相同的对象Teacher(“riemann”,28)。 这就叫做引用拷贝

 

(2)、对象拷贝

创建对象本身的一个副本。

public class ObjectCopy {
    public static void main(String[] args) throws CloneNotSupportedException {
        Teacher teacher = new Teacher("riemann", 28);
        Teacher otherTeacher = (Teacher) teacher.clone();
        System.out.println(teacher);
        System.out.println(otherTeacher);
    }
}

class Teacher implements Cloneable {
    private String name;
    private int age;

    public Teacher(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Object clone() throws CloneNotSupportedException {
        Object object = super.clone();
        return object;
    }
}

输出结果:

com.test.Teacher@28a418fc
com.test.Teacher@5305068a

结果分析:由输出结果可以看出,它们的地址是不同的,也就是说创建了新的对象, 而不是把原对象的地址赋给了一个新的引用变量,这就叫做对象拷贝。

 注:深拷贝和浅拷贝都是对象拷贝

二、浅拷贝

(1)、定义

被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。即对象的浅拷贝会对“主”对象进行拷贝,但不会复制主对象里面的对象。”里面的对象“会在原来的对象和它的副本之间共享。

简而言之,浅拷贝仅仅复制所考虑的对象,而不复制它所引用的对象。

(2)、浅拷贝实例

public class ShallowCopy {
    public static void main(String[] args) throws CloneNotSupportedException {
        Teacher teacher = new Teacher();
        teacher.setName("riemann");
        teacher.setAge(28);

        Student student1 = new Student();
        student1.setName("edgar");
        student1.setAge(18);
        student1.setTeacher(teacher);

        Student student2 = (Student) student1.clone();
        System.out.println("-------------拷贝后-------------");
        System.out.println(student2.getName());
        System.out.println(student2.getAge());
        System.out.println(student2.getTeacher().getName());
        System.out.println(student2.getTeacher().getAge());

        System.out.println("-------------修改老师的信息后-------------");
        // 修改老师的信息
        teacher.setName("jack");
        System.out.println("student1的teacher为: " + student1.getTeacher().getName());
        System.out.println("student2的teacher为: " + student2.getTeacher().getName());

    }
}

class Teacher implements Cloneable {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

class Student implements Cloneable {
    private String name;
    private int age;
    private Teacher teacher;

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Teacher getTeacher() {
        return teacher;
    }

    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
    }

    public Object clone() throws CloneNotSupportedException {
        Object object = super.clone();
        return object;
    }
}

输出结果:

-------------拷贝后-------------
edgar
18
riemann
28
-------------修改老师的信息后-------------
student1的teacher为: jack
student2的teacher为: jack

结果分析: 两个引用student1student2指向不同的两个对象,但是两个引用student1student2中的两个teacher引用指向的是同一个对象,所以说明是浅拷贝

 

三、深拷贝

(1)、定义

深拷贝是一个整个独立的对象拷贝,深拷贝会拷贝所有的属性,并拷贝属性指向的动态分配的内存。当对象和它所引用的对象一起拷贝时即发生深拷贝。深拷贝相比于浅拷贝速度较慢并且花销较大。

简而言之,深拷贝把要复制的对象所引用的对象都复制了一遍。

(2)、深拷贝实例

public class DeepCopy {
    public static void main(String[] args) throws CloneNotSupportedException {
        Teacher teacher = new Teacher();
        teacher.setName("riemann");
        teacher.setAge(28);

        Student student1 = new Student();
        student1.setName("edgar");
        student1.setAge(18);
        student1.setTeacher(teacher);

        Student student2 = (Student) student1.clone();
        System.out.println("-------------拷贝后-------------");
        System.out.println(student2.getName());
        System.out.println(student2.getAge());
        System.out.println(student2.getTeacher().getName());
        System.out.println(student2.getTeacher().getAge());

        System.out.println("-------------修改老师的信息后-------------");
        // 修改老师的信息
        teacher.setName("jack");
        System.out.println("student1的teacher为: " + student1.getTeacher().getName());
        System.out.println("student2的teacher为: " + student2.getTeacher().getName());
    }
}

class Teacher implements Cloneable {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

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

class Student implements Cloneable {
    private String name;
    private int age;
    private Teacher teacher;

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Teacher getTeacher() {
        return teacher;
    }

    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
    }

    public Object clone() throws CloneNotSupportedException {
        // 浅复制时:
        // Object object = super.clone();
        // return object;

        // 改为深复制:
        Student student = (Student) super.clone();
        // 本来是浅复制,现在将Teacher对象复制一份并重新set进来
        student.setTeacher((Teacher) student.getTeacher().clone());
        return student;

    }
}

输出结果:

-------------拷贝后-------------
edgar
18
riemann
28
-------------修改老师的信息后-------------
student1的teacher为: jack
student2的teacher为: riemann

结果分析:
两个引用student1student2指向不同的两个对象,两个引用student1student2中的两个teacher引用指向的是两个对象,但对teacher对象的修改只能影响student1对象,所以说是深拷贝

 

参考:

Java深入理解深拷贝和浅拷贝区别

 

标签:Java,name,Teacher,age,teacher,深入,拷贝,public
From: https://www.cnblogs.com/super-chao/p/18612869

相关文章

  • 基于Java中的SSM框架实现理发店管理系统项目【项目源码+论文说明】
    摘要随着信息化时代的到来,管理系统都趋向于智能化、系统化,理发店管理系统也不例外,但目前国内的市场仍都使用人工管理,市场规模越来越大,同时信息量也越来越庞大,人工管理显然已无法应对时代的变化,而理发店管理系统能很好地解决这一问题,轻松应对理发店管理的工作,既能提高人力物力......
  • 基于Java中的SSM框架实现美容院管理系统项目【项目源码+论文说明】
    摘要首先,论文一开始便是清楚的论述了系统的研究内容。其次,剖析系统需求分析,弄明白“做什么”,分析包括业务分析和业务流程的分析以及用例分析,更进一步明确系统的需求。然后在明白了系统的需求基础上需要进一步地设计系统,主要包罗软件架构模式、整体功能模块、数据库设计......
  • java复学——一步步走
    idea创建一个mavenwebapp空项目,手动配置springmvc教程<dependencies><!--springMVC坐标--><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId>......
  • node.js毕设基于Java的自习教室预约管理系统 论文+程序
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容一、选题背景关于自习教室预约管理系统的研究,现有研究主要以整体的教室资源管理为主,专门针对基于Java开发的自习教室预约管理系统的研究较少。在国内外,教室资源管理......
  • Java四大内部类之局部内部类、匿名内部类
    目录一、局部内部类二、匿名内部类基于接口的匿名内部类基于类的匿名内部类三、匿名内部类的实践类的五大成员:属性、方法、构造器、代码块、内部类内部类的分类定义在外部类局部位置上(比如说方法内):局部内部类(有类名)匿名内部类(没有类名)定义在外部类的成员位置......
  • 深入理解 Vue 3 中的 h 函数
    1.什么是h函数?h函数是Vue3中用来创建虚拟节点(VNode)的工具,它的本质是createVNode方法的简写。h函数的语法签名如下:h(type,props?,children?)type:节点的类型,可以是HTML标签(如'div')、组件或函数。 props:节点的属性对象,例如class、style、事件监听器等。......
  • 精通Java:如何在Windows中配置环境变量并轻松切换版本
    文章目录引言步骤1:安装Java1.1下载java1.2安装java步骤2:配置环境变量2.1配置JAVA_HOME2.2配置Path变量步骤3:验证配置3.1.打开命令提示符CMD3.2.验证java3.3验证Javac更换Java版本引言Java环境变量的配置是Java开发中一个重要的步骤。正确配置环境变量可以......
  • 【华为OD-E卷-寻找链表的中间结点 100分(python、java、c++、js、c)】
    【华为OD-E卷-寻找链表的中间结点100分(python、java、c++、js、c)】题目给定一个单链表L,请编写程序输出L中间结点保存的数据。如果有两个中间结点,则输出第二个中间结点保存的数据。例如:给定L为1→7→5,则输出应该为7;给定L为1→2→3→4,则输出应该为3;输入描述......
  • 【华为OD-E卷-字符串重新排序 字符串重新排列 100分(python、java、c++、js、c)】
    【华为OD-E卷-字符串重新排序字符串重新排列100分(python、java、c++、js、c)】题目给定一个字符串s,s包括以空格分隔的若干个单词,请对s进行如下处理后输出:1、单词内部调整:对每个单词字母重新按字典序排序2、单词间顺序调整:1)统计每个单词出现的次数,并按次数降序排列2)次......
  • Windows和Linux系统中安装JDK(Java Development Kit)
    一、在Windows系统中安装JDK下载JDK访问Oracle官方网站(https://www.oracle.com/java/technologies/javase-downloads.html)。根据你的操作系统(32位或64位)和需求,选择合适的JDK版本进行下载。例如,对于大多数普通开发,选择JavaSE(StandardEdition)的JDK安装包。运行安装程序......