Java深入理解深拷贝和浅拷贝区别[通俗易懂]

Java深入理解深拷贝和浅拷贝区别[通俗易懂]一、拷贝的引入(1)、引用拷贝创建一个指向对象的引用变量的拷贝。Teacherteacher=newTeacher("Taylor",26);Teacherotherteacher=teacher;System.out.println(teacher);System.out.println(otherteacher);输出结果:blog.Teacher@355da2…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

欢迎大家关注我的公众号【老周聊架构】,Java后端主流技术栈的原理、源码分析、架构以及各种互联网高并发、高性能、高可用的解决方案。

一、拷贝的引入

(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对象,所以说是深拷贝

在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/186946.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • a4纸两版的小册子怎么打印_word怎么打印小册子用a4

    a4纸两版的小册子怎么打印_word怎么打印小册子用a4用word打印小册子具体操作步骤:1、首先打开将要打印的文档,然后在菜单栏下面的快捷菜单栏,找到打印机的快捷图标,单击鼠标左键选择打开打印机。2、会弹出打印机设置对话框,可以进行打印前的一些细节的设置,由于是要选择打印一本小册子所以选择打印“所有页面”。3、在下面一栏是调整页面大小,也就是打印模式,选择“小册子”进行打印。4、然后下面是关于小册子的一些设置,按照自己的需要进行设置。5、设置完成以后…

  • Kafka集群原理

    Kafka集群原理Kafka是一个分布式的、可水平扩展的、基于发布/订阅模式的、支持容错的消息系统。一、集群成员Kafka使用Zookeeper来维护集群成员的信息。每个broker都有一个唯一标识符,这个标识符可以在配置文件里指定,也可以自动生成。在broker启动的时候,它通过创建临时节点把自己的ID注册到Zookeeper。Kafka组件订阅Zookeeper的/broker/ids路径,当有broker加入集群或退出集群时,这些组件就可以获得通知。ZooKeeper两.

  • Oracle 11g安装教程_oracle11g数据库教程

    Oracle 11g安装教程_oracle11g数据库教程11684小编花了一个多小时才把Oracle11g安装折腾好了,其中有些步骤可能很多人不知道怎么选择,本篇文章就为大家介绍下如何安装Oracle11g,11684小编折腾SQLDeveloper花了好长时间,总算搞定了。好了,先总结下安装步骤,希望给后面的朋友提高安装效率,11684分享过来!授权:免费软件类型:国产软件语言:简体中文大小:2.1GB日期:2016-03-23环境:Win…

  • Linux学习——shell编程之正则表达式和字符处理命令

    shell编程之正则表达式一 正则表达式 1 什么是正则表达式 正则表达式用于描述字符排列和匹配模式的一种语法规则。它主要用于字符串的模式分隔、匹配、查找及替换操作。2 shell编程之正则表达式与通配符 正则表达式:用于在文件中匹配符合条件的字符串。正则是包含匹配。grep 、awk 、sed等命令支持正则表达式。 通配符:用于匹配符合条件的文件名,通配符是完全匹配。ls、f

  • 手把手教你如何获取微信公众号用户的个人信息(包括OpenId)

    手把手教你如何获取微信公众号用户的个人信息(包括OpenId)最近,对微信公众号有点兴趣,就自己研究了研究里面的一些内容,发现还挺有意思的,而且通过微信公众号可以调用一些比较有意思的接口,就比如百度开发服务平台点击进入里面的很有接口,就比较常见的翻译,语音识别,地理位置等等,都挺好的。好了,不多说,进入正题好了。我想,做微信公众号开发的,对于想获取关注了公众号的用户信息,或者说是当前与后台服务器进行交互的当前用户信息,这个功能是很重要…

  • 计算机语言有哪些_计算机英语第五版刘艺pdf

    计算机语言有哪些_计算机英语第五版刘艺pdf计算机程序设计艺术 第3卷 排序和查找(英文影印版.第2版)

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号