浅谈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个概念,觉得它们是一回事,事实上则不然.今天我们就来一起 ...
随机推荐
- manacher hihoCoder1032 最长回文子串
居然能够做到O(n)的复杂度求最长回文.,也是给跪了. 以下这个人把manacher讲的很好,,能够看看 http://blog.csdn.net/xingyeyongheng/article/det ...
- gitlab的安装和配置
1 使用omnibus gitlab来安装gitlab 也就是说,将gitlab和它所需要的组件打一个包,即打一个bundle进行安装. 第一步,安装gitlab的源. curl https://pa ...
- C语言8大经典排序算法(1)
算法一直是编程的基础,而排序算法是学习算法的开始,排序也是数据处理的重要内容.所谓排序是指将一个无序列整理成按非递减顺序排列的有序序列.排列的方法有很多,根据待排序序列的规模以及对数据的处理的要求,可 ...
- CSU 1807: 最长上升子序列~ 分类讨论
1807: 最长上升子序列~ Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 138 Solved: 17[Submit][Status][Web Bo ...
- Cocos2d-x 3.2编译生成Android程序出错Error running command, return code: 2的解决方法
用Cocos2d-x 3.2正式版创建项目,结果使用cocos compile -p android编译生成APK程序,结果悲剧了,出现以下错误. Android NDK: Invalid APP_S ...
- BZOJ_1584_[Usaco2009 Mar]Cleaning Up 打扫卫生_DP
BZOJ_1584_[Usaco2009 Mar]Cleaning Up 打扫卫生_DP Description 有N头奶牛,每头那牛都有一个标号Pi,1 <= Pi <= M <= ...
- ZOJ 3956 Course Selection System 背包DP
ZOJ3956 观察数据范围, c的值非常小 只有100 所以c的和也很有限 只有50000 是否可以从这里下手? 对于某一个c的和 我们一定希望h的和最大 才有可能是最终答案. 于是有了类似背包的d ...
- springcloud 向Eureka中注册服务异常java.net.ConnectException: Connection refused: connect
异常如下: 通过debug发现,服务端的url地址仍然是默认的http://localhost:8761/eureka/apps/,也就是说yml文件中配置没有生效,检查后发现yml中相关配置多写了一 ...
- 【WIP】数据结构与算法入门
创建: 2017/12/25
- js最全的十种跨域解决方案
在客户端编程语言中,如javascript和ActionScript,同源策略是一个很重要的安全理念,它在保证数据的安全性方面有着重要的意义.同 源策略规定跨域之间的脚本是隔离的,一个域的脚本不能访问 ...