拷贝的实现:
只有子类实现了Cloneable接口后才可以使用Object类提供的clone方法。
protected native Object clone() throws CloneNotSupportedException;
Cloneable也是一个标识接口:public interface Cloneable { }

要想让对象具有拷贝的功能,必须实现Cloneable接口,并且在类中自定义clone() 调用Object类提供的继承权限clone方法。

浅拷贝:浅拷贝就是对对象的值(对于基本数据类型而言,值就是内容,对于引用类型,值就是它所指向的地址)进行拷贝。
浅拷贝存在的的问题:牵一发而动全身
只要任何一个拷贝对象(或原对象)中的引用发生了变化,所有的对象都会受到影响
直接来看个例子:

class Teacher{private String name;private String job;public Teacher(String name, String job) {this.name = name;this.job = job;}
}
// 1,实现Cloneable接口
class Student implements Cloneable{private String name;private int age;private Teacher teacher;public Student(String name, int age, Teacher teacher) {this.name = name;this.age = age;this.teacher = teacher;}// 2, 自己定义clone()public Student clone(){Student student = null;try {// 实现拷贝处理// 产生一个新的student对象,并且拷贝原有所有属性值student = (Student) super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();}return student;}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 static void main(String[] args) {Teacher teacher = new Teacher("张三百","Teacher");Student student = new Student("王五",10,teacher);Student studentClone = student.clone();System.out.println(student);System.out.println(studentClone); // 两个地址不同,有拷贝了新的对象System.out.println("-------------------------------------");System.out.println(studentClone.getAge());System.out.println(student.getAge());System.out.println(studentClone.getName());System.out.println(student.getName()); // 属性都相同,拷贝到了结果System.out.println("---------------------------------------");// 结果为true,拷贝对象和原对象共同引用teacherSystem.out.println(teacher == studentClone.getTeacher());}
}


从运行结果我们可以看到我们确实拷贝到了student对象的克隆对象studentClone,而且两者的所有属性都相同,并且也指向了同一个对象teacher。如下图。

深拷贝:理解了浅拷贝就不难理解深拷贝了,深拷贝拷贝出来的对象产生了所有引用的新对象。
特点:任何对象的改变不会对其他对象产生影响
深拷贝的实现有两种方式:

  1. 递归实现深拷贝:如果要拷贝的对象中包含对其他对象的引用,则让那个被引用的对象所在的类也实现Cloneable接口,和clone方法。
  2. 序列化实现深拷贝:使用序列化实现深拷贝时,无需再实现Clonable接口,只需要实现Serializable接口即可,但是clone()还是要写的。
    对序列化有疑问的,可以看java对象的序列化与反序列化
    看两个例子:
    递归实现深拷贝:
// Student引用了Teacher,Teacher也需要序列化
class Teacher implements Cloneable{private String name;private String job;public Teacher clone(){Teacher teacher = null;try {teacher = (Teacher) super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();}return teacher;}public Teacher(String name, String job) {this.name = name;this.job = job;}
}
class Student implements Cloneable{private String name;private int age;private Teacher teacher;public Student(String name, int age, Teacher teacher) {this.name = name;this.age = age;this.teacher = teacher;}public Student clone(){Student student = null;try {student = (Student) super.clone();// 产生新的引用student.teacher = this.teacher.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();}return student;}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 class Test {public static void main(String[] args) {Teacher teacher = new Teacher("张三百","Teacher");Student student = new Student("王五",10,teacher);Student studentClone = student.clone();System.out.println(student);System.out.println(studentClone);System.out.println("-------------------------------------");System.out.println(studentClone.getAge());System.out.println(student.getAge());System.out.println(studentClone.getName());System.out.println(student.getName());System.out.println("---------------------------------------");System.out.println(teacher == studentClone.getTeacher());}
}


从结果可以看到,拷贝对象与原对象确实对teacher的引用不同。

序列化实现深拷贝:

import java.io.*;
// 序列化实现深拷贝
class Teacher implements Serializable{private String name;private String job;public Teacher clone(){Teacher teacher = null;try {teacher = (Teacher) super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();}return teacher;}public Teacher(String name, String job) {this.name = name;this.job = job;}
}
class Student implements Serializable{private String name;private int age;private Teacher teacher;public Student(String name, int age, Teacher teacher) {this.name = name;this.age = age;this.teacher = teacher;}public Student cloneObject() throws Exception{Student student = null;ByteOutputStream bos = new ByteOutputStream();ObjectOutputStream oos = new ObjectOutputStream(bos);oos.writeObject(this);//参数是从内存中把数据读进来ByteArrayInputStream bis = new ByteArrayInputStream(bos.getBytes());ObjectInputStream ois = new ObjectInputStream(bis);// 从内存中反序列化出来return (Student) ois.readObject();}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 class Test {public static void main(String[] args) throws Exception{Teacher teacher = new Teacher("张三百","Teacher");Student student = new Student("王五",10,teacher);Student studentClone = student.cloneObject();System.out.println(student);System.out.println(studentClone);System.out.println("-------------------------------------");System.out.println(studentClone.getAge());System.out.println(student.getAge());System.out.println(studentClone.getName());System.out.println(student.getName());System.out.println("---------------------------------------");System.out.println(teacher == studentClone.getTeacher());}
}

其实除了深浅拷贝,还有延迟拷贝,我们可以理解为延迟拷贝就是深拷贝+浅拷贝
演出拷贝在对象只需要读取时采用浅拷贝,在需要对值做修改时采用深拷贝。

java:深拷贝与浅拷贝相关推荐

  1. 面试官:Java深拷贝和浅拷贝区别

    文章目录 一.拷贝的引入 (1).引用拷贝 (2).对象拷贝 二.浅拷贝 (1).定义 (2).浅拷贝实例 三.深拷贝 (1).定义 (2).深拷贝实例 一.拷贝的引入 (1).引用拷贝 创建一个指向 ...

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

    文章目录 1. 深拷贝和浅拷贝的区别 1.1 浅拷贝实例 1.1.1 测试1 直接赋值 1.1.2 测试2 改变源对象的值 1.2 深拷贝实例 `这是用于深拷贝的测试类` 1.2.1 方法一: 构造函 ...

  3. Java深拷贝与浅拷贝

    前言 对象拷贝Object Copy是将一个对象的属性,拷贝到另一个相同类型的对象中.拷贝对象主要是为了在新的上下文环境中复用对象的部分或全部数据.其中对象拷贝有3种类型:深拷贝Deep Copy.浅 ...

  4. java 深拷贝和浅拷贝

    深拷贝和浅拷贝的问题无非就是拷贝过程中对象的属性是否指向的是同一个对象引用. 浅拷贝的特点: 一:作为基本数据类型来说,例如int ,double等8类数据类型,拷贝过程中肯定是值的传递,修改另一个对 ...

  5. 浅谈对java深拷贝与浅拷贝的理解

    java中什么是浅拷贝?什么是深拷贝? 1.拷贝:实现对象复制的方式. 2.浅拷贝:被复制的对象的所有变量都含有原来对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之, 浅拷贝仅仅复制所 ...

  6. java深拷贝和浅拷贝_Java 深拷贝浅拷贝 与 序列化

    一.浅拷贝.深拷贝 浅拷贝会对对象中的成员变量进行拷贝:如果是基本类型,拷贝的就是基本类型的值:如果属性是内存地址(引用类型),拷贝的就是内存地址 : 深拷贝,除了基本类型外,引用类型所引用的对象也会 ...

  7. java深拷贝和浅拷贝介绍

    浅拷贝概念 深拷贝概念 @Data @Slf4j public class Sheep implements Cloneable {private String name;private int ag ...

  8. java 深拷贝_java 深拷贝与浅拷贝机制详解

    java 深拷贝与浅拷贝机制详解 概要: 在Java中,拷贝分为深拷贝和浅拷贝两种.java在公共超类Object中实现了一种叫做clone的方法,这种方法clone出来的新对象为浅拷贝,而通过自己定 ...

  9. java拷贝函数_Java的深拷贝与浅拷贝的几种实现方式

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

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

    title: Java 深入理解深拷贝和浅拷贝区别 date: 2021-6-19 updated: 2021-6-19 tags: Java 深拷贝和浅拷贝 categories: 面试 Java ...

最新文章

  1. Bootstrap框架和inconfont、font-awesome使用
  2. Oracle 12c coming soon?
  3. 在html中不是链接目标属性,在HTML中,()不是链接的目标属性。
  4. 神经网络为什么可以实现分类?---三分类网络0,1,2与弹性振子力学系统
  5. 前n个正整数相乘的时间复杂度为_初一数学必学必考的21个知识点,附第一章有理数测试卷...
  6. Java总结篇系列:Java泛型
  7. 在JS中如何判断undefined和null
  8. windows 8文件操作帮助类FileHelper
  9. flask redis_在Flask应用程序中将Redis队列用于异步任务
  10. Qt使用socket通信时接收的汉字信息显示时乱码
  11. arduino naon介绍_Arduino Nano 自制版
  12. SakaiCLE2.9数据库迁移
  13. 畅易阁老是显示服务器忙,畅易阁全服开放 盘点天龙玩家卖号的几大原因
  14. 桥接模式(Birdge)
  15. 利用grep-console插件使Intellij idea显示多颜色调试日志
  16. Windows Me光盘启动安装过程
  17. 资讯类APP消息推送系统的产品设计
  18. android 锁屏代码分析,锁屏分析(Android9.0)
  19. 使用OpenCV实现运动背景的重建
  20. 服务异步通信RabbitMQ

热门文章

  1. GCC 11 的静态分析功能将得到增强
  2. 执行时长 为了充分发挥GPU算力需要尽可能多的将任务交给GPU执行
  3. c语言字符串碱基互补配对,C++ 6.0 配对碱基链 自己编的程序输出总是有问题 求解...
  4. 基于html+css的图展示104
  5. 如何将上传到优酷的视频加载到网页中?
  6. 生态“群海”:数字化转型的供需之变
  7. 手势识别智能传感器发展和未来的探究
  8. 02 类加载器子系统
  9. 什么是happens-before原则?
  10. python安装gutenberg(windows)