浅谈java浅拷贝和深拷贝
前言:深拷贝和浅拷贝的区别是什么? 浅拷贝:被复制的对象的所有变量都含有原来对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之, 浅拷贝仅仅复制所考虑的对象,而不复制它所引用的对象。深拷贝:被复制对象的所有变量都含有与原来对象相同的值,而那些引用对象的变量将指向被复制过的新对象,而不再是原有 的那些被引用的对象。换言之,深拷贝把要复制的对象所引用的对象都复制了一遍。
浅拷贝
无论是浅拷贝还是深拷贝都要用到clone()方法,所有类都继承于Object,clone方法定义于Object类中但没有实现,
而如果要使用clone方法,根据源码则必须实现Cloneable接口,java.lang.Cloneable是一个标志性接口不包含任何方法,根据注释clone方法是由C或C++其他本地语言实现的。
* @return a clone of this instance.
* @throws CloneNotSupportedException if the object's class does not
* support the {@code Cloneable} interface. Subclasses
* that override the {@code clone} method can also
* throw this exception to indicate that an instance cannot
* be cloned.
* @see java.lang.Cloneable
*/
protected native Object clone() throws CloneNotSupportedException;
实现浅拷贝:
package yunche.test.copy; /**
* @ClassName: Dog
* @Description:
* @author: yunche
* @date: 2018/08/25
*/
public class Dog implements Cloneable
{
public String color;
public int age; /**
* 引用变量
*/
public Erha erha; public static void main(String[] args) throws CloneNotSupportedException
{
Dog d = new Dog();
d.color="yellow";
d.age=2;
d.erha = new Erha();
d.erha.name = "二哈"; //此时clone方法为浅拷贝
Dog copyDog = (Dog)d.clone();
System.out.println(copyDog.color);
System.out.println(copyDog.age);
System.out.println(copyDog.erha.name); //hashcode不同,创建了新对象
System.out.println(d==copyDog);
System.out.println(d.hashCode());
System.out.println(copyDog.hashCode()); //hashcode相同,没有创建新的erha对象,只是复制了引用
System.out.println(copyDog.erha==d.erha);
System.out.println(copyDog.erha.hashCode());
System.out.println(d.erha.hashCode()); } private static class Erha
{
String name;
}
}

深拷贝
深拷贝对于基本数据类型进行值传递,对引用数据类型,创建一个新的对象。并复制其内容。怎么实现深拷贝呢?通常的方案有两种:1.序列化这个对象,再反序列化回来,就可以得到这个新的对象,序列化的规则需要我们自己来写。2.重写clone方法,我们可以对其内部引用类型的变量,再进行一次clone()。
序列化方式
序列化需要实现Serializable接口。
package yunche.test.copy; import java.io.*; /**
* @ClassName: Dog
* @Description:
* @author: yunche
* @date: 2018/08/25
*/
public class Dog implements Cloneable, Serializable
{
public String color;
public int age; /**
* 引用变量
*/
public Erha erha; public static void main(String[] args) throws CloneNotSupportedException
{
Dog d = new Dog();
d.color="yellow";
d.age=2;
d.erha = new Erha();
d.erha.name = "二哈"; Dog copyDog = (Dog)d.deepClone();
System.out.println(copyDog.color);
System.out.println(copyDog.age);
System.out.println(copyDog.erha.name); //hashcode不同,创建了新对象
System.out.println(d==copyDog);
System.out.println(d.hashCode());
System.out.println(copyDog.hashCode()); //hashcode不同,创建新的erha对象,实现了深拷贝
System.out.println(copyDog.erha==d.erha);
System.out.println(copyDog.erha.hashCode());
System.out.println(d.erha.hashCode()); } public Object deepClone()
{
File f = new File("dog.obj");
Object obj =null;
try(FileOutputStream fos = new FileOutputStream(f);
ObjectOutputStream oos = new ObjectOutputStream(fos);
FileInputStream fis = new FileInputStream(f);
ObjectInputStream ois = new ObjectInputStream(fis))
{
oos.writeObject(this);
obj = ois.readObject();
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
return obj;
} private static class Erha implements Serializable
{
String name;
}
}

重写clone
package yunche.test.copy; import java.io.*; /**
* @ClassName: Dog
* @Description:
* @author: yunche
* @date: 2018/08/25
*/
public class Dog implements Cloneable
{
public String color;
public int age; /**
* 引用变量
*/
public Erha erha; public static void main(String[] args) throws CloneNotSupportedException
{
Dog d = new Dog();
d.color="yellow";
d.age=2;
d.erha = new Erha();
d.erha.name = "二哈"; //重新clone方法,实现深拷贝
Dog copyDog = (Dog)d.clone();
System.out.println(copyDog.color);
System.out.println(copyDog.age);
System.out.println(copyDog.erha.name); //hashcode不同,创建了新对象
System.out.println(d==copyDog);
System.out.println(d.hashCode());
System.out.println(copyDog.hashCode()); //hashcode不同,创建新的erha对象,实现了深拷贝
System.out.println(copyDog.erha==d.erha);
System.out.println(copyDog.erha.hashCode());
System.out.println(d.erha.hashCode()); } @Override
public Object clone()
{
try
{
Dog dog = (Dog)super.clone();
dog.erha = (Erha) this.erha.clone();
return dog; }
catch (CloneNotSupportedException e)
{
e.printStackTrace();
}
return null;
} public static class Erha implements Cloneable
{
String name; @Override
public Object clone()
{
try
{
return super.clone();
}
catch (CloneNotSupportedException e)
{
e.printStackTrace();
}
return null;
}
}
}

参考资料
https://segmentfault.com/a/1190000010648514
浅谈java浅拷贝和深拷贝的更多相关文章
- 浅谈Java中的深拷贝和浅拷贝(转载)
浅谈Java中的深拷贝和浅拷贝(转载) 原文链接: http://blog.csdn.net/tounaobun/article/details/8491392 假如说你想复制一个简单变量.很简单: ...
- 浅谈Java中的深拷贝和浅拷贝
转载: 浅谈Java中的深拷贝和浅拷贝 假如说你想复制一个简单变量.很简单: int apples = 5; int pears = apples; 不仅仅是int类型,其它七种原始数据类型(bool ...
- 浅谈C#浅拷贝和深拷贝
近来爱上一本书<编写高质量代码,改善C#程序的157个建议>,我想很多人都想编写高质量的代码,因为我们不仅仅是码农,更是一名程序员. 从今天开始,我将每天和大家分享这本书中的内容,并加上自 ...
- java基础(十七)----- 浅谈Java中的深拷贝和浅拷贝 —— 面试必问
假如说你想复制一个简单变量.很简单: int apples = 5; int pears = apples; 不仅仅是int类型,其它七种原始数据类型(boolean,char,byte,short, ...
- 浅谈Javascript 浅拷贝和深拷贝的理解
javascript中存储对象都是存地址的. 浅拷贝:浅拷贝是都指向同一块内存区块,浅拷贝共用同一内存地址,你改值我也变.如果拷贝的对象里面的值是一个对象或者数组,它就是浅拷贝,拷贝的知识引用地址. ...
- Java 浅拷贝、深拷贝,你知多少?
这是今天我们在技术群里面讨论的一个知识点,讨论的相当激烈,由于对这一块使用的比较少,所以对这一块多少有些盲区.这篇文章总结了所讨论的内容,希望这篇文章对你有所帮助. 在 Java 开发中,对象拷贝或者 ...
- 浅谈Java的throw与throws
转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...
- 浅谈Java中的equals和==(转)
浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new String("hello"); 2 String str ...
- 浅谈Java中的对象和引用
浅谈Java中的对象和对象引用 在Java中,有一组名词经常一起出现,它们就是“对象和对象引用”,很多朋友在初学Java的时候可能经常会混淆这2个概念,觉得它们是一回事,事实上则不然.今天我们就来一起 ...
随机推荐
- 前端为啥要用javascript框架
前端使用EXT.JS,如果存在两个控件,其中A控件的ID 与 B控件的name相同的话,会报错.ID不能存在相同的情况众所周知,而不同的控件,name也不能相同,恐怕只有遇到过的人才知道了,这不,我就 ...
- 定时删除clientmqueue
* * */1 * * cd /var/spool; cp -r clientmqueue /home/data/xl_project/var_spool_clientmqueue_$(date + ...
- Hibernate - Query简易
package cn.demo; import java.util.List; import org.hibernate.Query; import org.hibernate.Session; im ...
- HttpClient-03Http状态管理
最初,Http被设计成一个无状态的,面向请求/响应的协议,所以它不能在逻辑相关的http请求/响应中保持状态会话.由于越来越多的系统使用http协议,其中包括http从来没有想支持的系统,比如电子商务 ...
- Massive Data Mining学习记录
第一周: 学习PageRank, 知识点:每个节点的权值由其他节点的投票决定,所有节点的权值和为1 当节点很多时候必须转换成矩阵运算来计算节点的最终值,由马尔可夫链可以证明,这个值可以迭代得到 问题: ...
- HDU 1379:DNA Sorting
DNA Sorting Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Tota ...
- 洛谷 P1181,1182 数列分段Section
数列分段Section I 题目描述 对于给定的一个长度为N的正整数数列A[i],现要将其分成连续的若干段,并且每段和不超过M(可以等于M),问最少能将其分成多少段使得满足要求. 输入输出格式 输入格 ...
- mac ox终端显示 bogon的问题
mac终端显示如果正常应该是电脑名称(偏好设置-共享)的,但是细心的我们会发现,当电脑换了网络环境之后,可能就会出现终端上显示为主机名为:bogon,一查bogon这个单词是虚拟.虚伪的意思. ...
- 51Nod 1522 上下序列 —— 区间DP
题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1522 区间DP,从大往小加: 新加入一种数有3种加法:全加左边,全 ...
- Python 之reduce()函数
reduce()函数: reduce()函数也是Python内置的一个高阶函数.reduce()函数接收的参数和 map()类似,一个函数 f,一个list,但行为和 map()不同,reduce() ...