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 ...
随机推荐
- RabbitMQ学习总结(3)-集成SpringBoot
1. pom.xml引用依赖 SpringBoot版本可以自由选择,我使用的是2.1.6.RELEASE,使用starter-web是因为要使用Spring的相关注解,所以要同时加上. <dep ...
- Chrome太占内存?试试这个
" The Great Suspender" 是一个免费的开源 Google Chrome 扩展程序,适用于那些发现chrome占用过多系统资源或经常遭受chrome崩溃的人. 一 ...
- kubernetes 中安装 heapster 问题
step1: 在官网下载部署文件 https://github.com/kubernetes-retired/heapster/tree/master/deploy/kube-config/influ ...
- 035_go语言中的速率限制
代码演示 package main import "fmt" import "time" func main() { requests := make(chan ...
- html笔记 标签属性、图像和链接、超链接
HTML 标签属性: <b></b>:加粗 <i></i>:斜体 <u></u>:下划线 <s></s> ...
- Spring IOC 剖析
模拟实现 Spring Ioc 控制反转功能 使用 => 原理 => 源码 => 模拟实现 使用:了解 原理:熟悉 源码 And 模拟实现: 精通 对照 Spring 功能点 Spr ...
- DIFF算法浅析(三)在react中的实现
在虚拟dom中diff的实现. 分别从4个方面: DIFF抽象概念(概述.时间复杂性分析) 在Vue2中的实现(版本2.6.11.必要性.执行方式) 在React中的实现(版本16.13.1,必要性. ...
- 面试官:怎么做JDK8的垃圾收集器的调优?
面试官:怎么做JDK8的垃圾收集器的调优? 看着面试官真诚的眼神,心中暗想看起来年纪轻轻却提出如此直击灵魂的问题.擦了擦额头上汗,我稍微调整了一下紧张的情绪,对面试官说: 在JDK8中有Serial收 ...
- LeetCode 122 best-time-to-buy-and-sell-stock-ii 详解
题目描述 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你可以尽可能地完成更多的交易(多次买卖一支股票). 注意:你不能同时参与多笔交易(你 ...
- HTML实例-01-轮播图
body部分 <div class="outer"> <ul class="img-list"> <li><a hr ...