浅谈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个概念,觉得它们是一回事,事实上则不然.今天我们就来一起 ...
随机推荐
- 【codevs2011】【LNOI2013】最小距离之和
floyed水题 #include<algorithm> #include<iostream> #include<cstdlib> #include<cstr ...
- projecteuler---->problem=12----Highly divisible triangular number
title: The sequence of triangle numbers is generated by adding the natural numbers. So the 7th trian ...
- luogu 1726 上白泽惠音
题目大意: 给一个有向图 求一个最大的强连通分量,输出这个强连通分量里的所有元素 若两个联通分量内点数相同 则输出字典序小的那个 思路: 直接tarjan 对每个连通分量,求一下最小点,然后判断字典序 ...
- Window 无法启动此程序,因为计算机中丢失api-ms-win-crt-runtime-l1-1-0.dll。尝试重新安装该程序以解决此问题。
现象: 解决办法: 方法一:缺什么补什么 http://www.greenxf.com/soft/125654.html 把api-ms-win-crt-runtime-l1-1-0.dll下载到电脑 ...
- 洛谷P1514 引水入城——dfs
题目:https://www.luogu.org/problemnew/show/P1514 搜索+DP: 自己想出来的方法第一次80分好高兴! 再改了改就A了,狂喜乱舞: 也就是 dfs,仔细一想第 ...
- jquery plupload上传插件
http://www.jianshu.com/p/047349275cd4 http://www.cnblogs.com/2050/p/3913184.html demo地址: http://chap ...
- 解决Error for wireless request "Set Mode" (8B06) 问题 (转载)
转自:http://blog.csdn.net/muge0913/article/details/17062871 在运行以下命令的时候,意外的出错,最后google了下,最终才确定了原因,因为在运行 ...
- 【废弃】【WIP】JavaScript Object
创建: 2017/11/03 废弃: 2019/02/19 重构此篇.原文归入废弃 增加[废弃中]标签与总体任务 结束: 2019/03/03 完成废弃, 删除[废弃中]标签, 添加[废弃]标签 T ...
- bzoj 4719: [Noip2016]天天爱跑步【树上差分+dfs】
长久以来的心理阴影?但是其实非常简单-- 预处理出deep和每组st的lca,在这里我简单粗暴的拿树剖爆算了 然后考虑对于一组s t lca来说,被这组贡献的观察员x当且仅当: x在s到lca的路径上 ...
- bzoj 1598: [Usaco2008 Mar]牛跑步【A*K短路】
A*K短路模板,详见https://blog.csdn.net/z_mendez/article/details/47057461 算法流程: 把有向图全建成反向边,跑一遍所有点到t的最短路记为dis ...