Java拷贝——深拷贝与浅拷贝
深拷贝和浅拷贝
值类型 vs 引用类型
// 学生的所学专业
public class Major {
private String majorName;
// 专业名称
private long majorId; // 专业代号
// ... 其他省略 ...
}
// 学生
public class Student {
private String name; // 姓名
private int age; // 年龄
private Major major; // 所学专业
// ... 其他省略 ...
}
赋值 vs 浅拷贝 vs 深拷贝
对象赋值
Student codeSheep = new Student();
Student codePig = codeSheep;
浅拷贝

深拷贝

浅拷贝代码实现
public class Student implements Cloneable {
private String name; // 姓名
private int age; // 年龄
private Major major; // 所学专业
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
// ... 其他省略 ...
}
public class Test { public static void main(String[] args) throws CloneNotSupportedException
{ Major m = new Major("计算机科学与技术",666666);
Student student1 = new Student("CodeSheep",18, m );
// 由 student1 拷贝得到 student2
Student student2 = (Student) student1.clone(); System.out.println( student1 == student2 );
System.out.println( student1 );
System.out.println( student2 );
System.out.println( "\n");
// 修改student1的值类型字段
student1.setAge( 35);
// 修改student1的引用类型字段
m.setMajorName( "电子信息工程");
m.setMajorId( 888888);
System.out.println( student1 );
System.out.println( student2 );
}
}

- student1==student2打印false,说明clone()方法的确克隆出了一个新对象;
- 修改值类型字段并不影响克隆出来的新对象,符合预期;
- 而修改了student1内部的引用对象,克隆对象student2也受到了波及,说明内部还是关联在一起的
深拷贝代码实现
1、深度遍历式拷贝
public class Major implements Cloneable { @Override protected Object clone() throws CloneNotSupportedException
{
return super.clone();
}
// ... 其他省略 ...
}
public class Student implements Cloneable {
@Override
public Object clone() throws CloneNotSupportedException
{
Student student = (Student) super.clone();
student.major = (Major) major.clone(); // 重要!!!
return student;
}
// ... 其他省略 ...
}

2、利用反序列化实现深拷贝
public class Student implements Serializable {
private String name; // 姓名
private int age; // 年龄
private Major major; // 所学专业
public Student clone() {
try {
// 将对象本身序列化到字节流
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream );
objectOutputStream.writeObject( this);
// 再将字节流通过反序列化方式得到对象副本
ObjectInputStream objectInputStream = new ObjectInputStream(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()));
return (Student) objectInputStream.readObject();
} catch(IOException e) {
e.printStackTrace();
} catch(ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
// ... 其他省略 ...
}
public class Major implements Serializable {
// ... 其他省略 ...
}

Java拷贝——深拷贝与浅拷贝的更多相关文章
- Java的深拷贝和浅拷贝
关于Java的深拷贝和浅拷贝,简单来说就是创建一个和已知对象一模一样的对象.可能日常编码过程中用的不多,但是这是一个面试经常会问的问题,而且了解深拷贝和浅拷贝的原理,对于Java中的所谓值传递或者引用 ...
- 细说 Java 的深拷贝和浅拷贝
版权声明: 本账号发布文章均来自公众号,承香墨影(cxmyDev),版权归承香墨影所有. 未经允许,不得转载. 一.前言 任何变成语言中,其实都有浅拷贝和深拷贝的概念,Java 中也不例外.在对一个现 ...
- 浅析java的深拷贝与浅拷贝
(转自:http://www.cnblogs.com/chenssy/p/3308489.html) 首先来看看浅拷贝和深拷贝的定义: 浅拷贝:使用一个已知实例对新创建实例的成员变量逐个赋值,这个方式 ...
- Java实现深拷贝和浅拷贝
1.类实现Cloneable才可以进行对象拷贝 2.Cloneable只实现浅拷贝,需要实现深拷贝的必须要重写clone()方法 3.利用反序列化也可以实现深拷贝,但是反序列化耗时较长 n.浅拷贝是指 ...
- 【Java】深拷贝和浅拷贝
Java中的对象拷贝(Object Copy)指的是将一个对象的所有属性(成员变量)拷贝到另一个有着相同类类型的对象中去.举例说明:比如,对象A和对象B都属于类S,具有属性a和b.那么对对象A进行拷贝 ...
- Python对象拷贝——深拷贝与浅拷贝
对象赋值 浅拷贝 深拷贝 1. 对象赋值 对象的赋值实际上是对对象的引用.也就是说当把一个对象赋值给另一个对象时,只是拷贝了引用.如: >>> t1 = tuple('furzoom ...
- java基础——深拷贝和浅拷贝的区别
浅拷贝:对基本数据类型进行值传递,对引用数据类型进行引用传递般的拷贝,此为浅拷贝. 深拷贝:对基本数据类型进行值传递,对引用数据类型船舰一个新的对象,并复制内容,这是深拷贝.
- Java问题解读系列之IO相关---Java深拷贝和浅拷贝
前几天和棒棒童鞋讨论Java(TA学的是C++)的时候,他提到一个浅拷贝和深拷贝的问题,当时的我一脸懵圈,感觉自己学Java居然不知道这个知识点,于是今天研究了一番Java中的浅拷贝和深拷贝,下面来做 ...
- java 深拷贝与浅拷贝
yls 2019年11月07日 拷贝分为引用拷贝和对象拷贝 深拷贝和浅拷贝都属于对象拷贝 浅拷贝:通过Object默认的clone方法实现 实现Cloneable接口 public class She ...
随机推荐
- 小波变换检测信号突变点的MATLAB实现
之前在不经意间也有接触过求突变点的问题.在我看来,与其说是求突变点,不如说是我们常常玩的"找不同".给你两幅图像,让你找出两个图像中不同的地方,我认为这其实也是找突变点在生活中的应 ...
- 【NOIP2013】火柴排队 题解(贪心+归并排序)
前言:一道水题. ----------------------- 题目链接 题目大意:给出数列$a_i$和$b_i$,问使$\sum_{i=1}^n (a_i-b_i)^2$最小的最少操作次数. 首先 ...
- Spring Boot上传文件(带进度条)
Spring Boot 上传文件(带进度条)# 配置文件 spring: freemarker: template-loader-path: classpath:/static/ ##Spring B ...
- 22-关键字:super
1.super 关键字可以理解为:父类的 2.可以用来调用的结构: 属性.方法.构造器 3.super调用属性.方法: 3.1 我们可以在子类的方法或构造器中.通过使用"super.属性&q ...
- CSS样式大全(网络收集整理)
CSS样式大全(网络收集整理 字体属性:(font) 大小 {font-size: x-large;}(特大) xx-small;(极小) 一般中文用不到,只要用数值就可以,单位:PX.PD 样式 { ...
- Python高性能HTTP客户端库requests的使用
Python中有许多HTTP客户端.使用最广泛且最容易的是requests. 持续连接 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手.很 ...
- 9、Bridge 桥梁模式 将类的功能层次结构与实现层结构分离 结构型设计模式
1.何为桥接模式 桥接模式是一种将类的功能层次和实现层次分离的技术,所谓类的功能层次指的是类要实现什么功能,要定义多少个函数还进行处理,在功能之中我们会用到继承来定义新的方法同时也能使用父类的方法,这 ...
- C# BackGroundWorker实现窗体不卡死 进度条功能
网上的例子少了好多属性的配置,改好了一个能直接用的: using System; using System.Collections.Generic; using System.ComponentMod ...
- 为什么我们需要Q#?
原文地址:https://blogs.msdn.microsoft.com/visualstudio/2018/11/15/why-do-we-need-q/ 本文章为机器翻译. 你可能熟悉微软量子的 ...
- Vue Element-UI 中列表单选的实现
el-table中单选的实现 引用场景: 选择单条数据进行业务操作 实现方式: 给el-table-column设置el-radio Template 代码 <div class="r ...