一、拷贝的引入


(1)、引用拷贝

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

Teacher teacher = new Teacher("Taylor",26);
Teacher otherteacher = teacher;
System.out.println(teacher);
System.out.println(otherteacher);

输出结果:

blog.Teacher@355da254
blog.Teacher@355da254

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

(2)、对象拷贝

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

Teacher teacher = new Teacher("Swift",26);
Teacher otherteacher = (Teacher)teacher.clone();
System.out.println(teacher);
System.out.println(otherteacher);

输出结果:

blog.Teacher@355da254
blog.Teacher@4dc63996

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

二、浅拷贝


(1)、定义

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

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

(2)、浅拷贝实例

package com.test;

public class ShallowCopy {
public static void main(String[] args) throws CloneNotSupportedException {
Teacher teacher = new Teacher();
teacher.setName("riemann");
teacher.setAge(27); Student2 student1 = new Student2();
student1.setName("edgar");
student1.setAge(18);
student1.setTeacher(teacher); Student2 student2 = (Student2) 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("Games");
System.out.println(student1.getTeacher().getName());
System.out.println(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 Student2 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
27
修改老师的信息后-------------
Games
Games

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

三、深拷贝


(1)、定义

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

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

(2)、深拷贝实例

package com.test;

public class DeepCopy {
public static void main(String[] args) throws CloneNotSupportedException {
Teacher2 teacher = new Teacher2();
teacher.setName("riemann");
teacher.setAge(27); Student3 student1 = new Student3();
student1.setName("edgar");
student1.setAge(18);
student1.setTeacher(teacher); Student3 student2 = (Student3) 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("Games");
System.out.println(student1.getTeacher().getName());
System.out.println(student2.getTeacher().getName());
}
} class Teacher2 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 Student3 implements Cloneable {
private String name;
private int age;
private Teacher2 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 Teacher2 getTeacher() {
return teacher;
} public void setTeacher(Teacher2 teacher) {
this.teacher = teacher;
} public Object clone() throws CloneNotSupportedException {
// 浅复制时:
// Object object = super.clone();
// return object; // 改为深复制:
Student3 student = (Student3) super.clone();
// 本来是浅复制,现在将Teacher对象复制一份并重新set进来
student.setTeacher((Teacher2) student.getTeacher().clone());
return student; }
}

输出结果:

拷贝后
edgar
18
riemann
27
修改老师的信息后-------------
Games
riemann

结果分析:

两个引用student1和student2指向不同的两个对象,两个引用student1和student2中的两个teacher引用指向的是两个对象,但对teacher对象的修改只能影响student1对象,所以说是深拷贝。

关于Java深拷贝和浅拷贝区别,你学废了么?

  • 区别:如果在拷贝这个对象的时候,只对基本数据类型进行了拷贝,而对引用类型数据只是进行了引用的传递,而没有真实的创建一个新的对象,则认为是浅拷贝。反之,在对引用类型数据进行拷贝的时候,创建了一个新的对象,并且复制其内的成员变量,则认为是深拷贝。

问:clone()方法,是对当前对象进行浅拷贝,引用类型依然是在传递引用,那么,如何进行一个深拷贝呢?

  • 序列化这个对象,再反序列化回来,就可得到这个新的对象,无非就是序列化的规则需要自己来写。
  • 继续利用clone()方法,既然clone()方法是我们来重写的,实际上可以对其内的引用类型的变量,在进行一次clone()。

Java的深拷贝和浅拷贝的区别的更多相关文章

  1. java基础——深拷贝和浅拷贝的区别

    浅拷贝:对基本数据类型进行值传递,对引用数据类型进行引用传递般的拷贝,此为浅拷贝. 深拷贝:对基本数据类型进行值传递,对引用数据类型船舰一个新的对象,并复制内容,这是深拷贝.

  2. Java的深拷贝和浅拷贝

    关于Java的深拷贝和浅拷贝,简单来说就是创建一个和已知对象一模一样的对象.可能日常编码过程中用的不多,但是这是一个面试经常会问的问题,而且了解深拷贝和浅拷贝的原理,对于Java中的所谓值传递或者引用 ...

  3. Python 深拷贝和浅拷贝的区别

    python的复制,深拷贝和浅拷贝的区别    在python中,对象赋值实际上是对象的引用.当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用  ...

  4. 细说 Java 的深拷贝和浅拷贝

    版权声明: 本账号发布文章均来自公众号,承香墨影(cxmyDev),版权归承香墨影所有. 未经允许,不得转载. 一.前言 任何变成语言中,其实都有浅拷贝和深拷贝的概念,Java 中也不例外.在对一个现 ...

  5. Python赋值语句与深拷贝、浅拷贝的区别

    参考:http://stackoverflow.com/questions/17246693/what-exactly-is-the-difference-between-shallow-copy-d ...

  6. python深拷贝和浅拷贝的区别

    首先深拷贝和浅拷贝都是对象的拷贝,都会生成一个看起来相同的对象,他们本质的区别是拷贝出来的对象的地址是否和原对象一样,也就是地址的复制还是值的复制的区别. 什么是可变对象,什么是不可变对象: 可变对象 ...

  7. c# 深拷贝与浅拷贝的区别分析及实例

    浅拷贝(影子克隆):只复制对象的基本类型,对象类型,仍属于原来的引用. 深拷贝(深度克隆):不紧复制对象的基本类,同时也复制原对象中的对象.就是说完全是新对象产生的. 深拷贝是指源对象与拷贝对象互相独 ...

  8. python深拷贝与浅拷贝的区别

    可变对象:一个对象在不改变其所指向的地址的前提下,可以修改其所指向的地址中的值 不可变对象:一个对象所指向的地址上值是不能修改的,如果你修改了这个对象的值,那么它指向的地址就改变了,相当于你把这个对象 ...

  9. 【python测试开发栈】—理解python深拷贝与浅拷贝的区别

    内存的浅拷贝和深拷贝是面试时经常被问到的问题,如果不能理解其本质原理,有可能会答非所问,给面试官留下不好的印象.另外,理解浅拷贝和深拷贝的原理,还可以帮助我们理解Python内存机制.这篇文章将会通过 ...

  10. Java拷贝——深拷贝与浅拷贝

    深拷贝和浅拷贝 值类型 vs 引用类型 在Java中,像数组.类Class.枚举Enum.Integer包装类等等,就是典型的引用类型,所以操作时一般来说采用的也是引用传递的方式: 但是Java的语言 ...

随机推荐

  1. 常用RE对照表——敬请期待!!!

    .* #任意长度任意字符

  2. MasaFramework -- 缓存入门与规则配置

    概念 什么是缓存,在项目中,为了提高数据的读取速度,我们会对不经常变更但访问频繁的数据做缓存处理,我们常用的缓存有: 本地缓存 内存缓存:IMemoryCache 分布式缓存 Redis: Stack ...

  3. 第二阶段:高级核心基础知识·第4章shell特性·2

    1.统计日志,日志内容 39.96.187.239 - - [11/Nov/2019:10:08:01 +0800] "GET / HTTP/1.1" 302 0 "-& ...

  4. Windows7下驱动开发与调试体系构建——3.调试体系概述

    目录/参考资料:https://www.cnblogs.com/railgunRG/p/14412321.html 调试体系概述 0.什么是自建调试体系? 就是复写windows的调试api,使得调试 ...

  5. Java单例模式,看这一篇就够了

    在创建型设计模式中,我们第一个学习的是单例模式(Singleton Pattern),这是设计模式中最简单的模式之一. 单例是什么意思呢? 单例就是单实例的意思,即在系统全局,一个类只创建一个对象,并 ...

  6. JS学习笔记 (五) 函数进阶

    1.函数基础 1.1 函数的基本概念 函数是一段JavaScript代码,只被定义一次,但是可以被调用或者执行许多次.函数是一种对象,可以设置属性,或调用方法. 函数中的参数分为实参和形参.其中,形参 ...

  7. 详细了解JVM运行时内存

    详细了解JVM运行时内存 1.程序计数器 概念 程序计数器也叫作PC寄存器,是一块很小的内存区域,可以看做是当前线程执行的字节码的行号指示器.字节码的解释工作就是通过改变程序计数器里面的值来获得下一条 ...

  8. 优化if、elif过多

    优化if ,elif过多的场景 字典的成员运算,是判断字典的key 思路:把函数的内存地址存到字典当中 def login():    pass def scan(): pass def transf ...

  9. 关于入门深度学习mnist数据集前向计算的记录

    import osimport lr as lrimport tensorflow as tffrom pyspark.sql.functions import stddevfrom tensorfl ...

  10. Java注解与原理分析

    目录 一.注解基础 二.注解原理 三.常用注解 1.JDK注解 2.Lombok注解 四.自定义注解 1.同步控制 2.类型引擎 五.参考源码 使用的太多,被忽略的理所当然: 一.注解基础 注解即标注 ...