java 克隆的浅拷贝与深拷贝
来源:互联网 发布:济南淘宝代运营公司 编辑:程序博客网 时间:2024/05/22 09:45
java中的克隆方法是clone();
当使用clone()方法去拷贝一个对象的时候,拷贝后的新对象与老对象是两个地址不同的对象
满足 :
老对象.clone() != 新对象
老对象.clone().getClass() == 新对象.geClass()
老对象.clone().equals(新对象) == true
但是 ,如果对象中成员变量包含对其他对象的引用的时候,用clone()方法克隆出来的新对象的引用同老对象的引用指向的是同一个对象,改变任何一个对象引用中的属性均对另一个产生影响。这就是clone()方法的浅拷贝
那么,如何将浅拷贝转换成深拷贝那,实现Cloneable接口,自己实现clone方法,并在clone方法中将对掐对象的引用也clone一份,这样克隆出来的新对象对其他对象的引用就同样拷贝了一份,实现了深层拷贝
<span style="font-size:18px;">public Object clone(){Student o = null;try {o = (Student)super.clone();o.p = (Person) p.clone(); //将引用也克隆一份} catch (CloneNotSupportedException e) {e.printStackTrace();}return o;}</span>
同样,还可以利用串行化进行深拷贝
把对象写到流里的过程是串行化(Serilization)过程,但是在Java程序师圈子里又非常形象地称为“冷冻”或者“腌咸菜(picking)”过程;而把对象从流中读出来的并行化(Deserialization)过程则叫做 “解冻”或者“回鲜(depicking)”过程。
应当指出的是,写在流里的是对象的一个拷贝,而原对象仍然存在于JVM里面,因此“腌成咸菜”的只是对象的一个拷贝,Java咸菜还可以回鲜。
在Java语言里深复制一个对象,常常可以先使对象实现Serializable接口,然后把对象(实际上只是对象的一个拷贝)写到一个流里(腌成咸菜),再从流里读出来(把咸菜回鲜),便可以重建对象。
public Object deepClone(){ByteArrayOutputStream bos; ObjectOutputStream oos;ByteArrayInputStream bis;ObjectInputStream ois;Object o =null;try {//将对象写到流中bos= new ByteArrayOutputStream();oos = new ObjectOutputStream(bos);oos.writeObject(this);//将流中的对象读出bis = new ByteArrayInputStream(bos.toByteArray());ois = new ObjectInputStream(bis);o= ois.readObject();} catch (IOException | ClassNotFoundException e) {e.printStackTrace();}return o;}//前提是此类和成员变量对象的应用实现Serializable接口
测试:
public static void main(String[] args) {Person p = new Person("王小二", 22, "北京市");Student s1 = new Student("小明", 12, p);Student s2 =(Student) s1.deepClone();//(Student) s1.clone();System.out.println("s1对象"+s1);System.out.println("s2对象"+s2);System.out.println("s1对象年龄:"+s1.age+" s1对象名字:"+s1.name+" s1对象的引用对象Person:"+s1.p);System.out.println("s2对象年龄:"+s2.age+" s2对象名字:"+s2.name+" s2对象的引用对象Person:"+s2.p);}测试结果
s1对象com.isoftstone.Student@d3db51
s2对象com.isoftstone.Student@bad8a8
s1对象年龄:12 s1对象名字:小明 s1对象的引用对象Person:com.isoftstone.Person@888e6c
s2对象年龄:12 s2对象名字:小明 s2对象的引用对象Person:com.isoftstone.Person@e61fd1
如果将引用的成员变量对象加上transient去修饰,再调用deepClone()方法,引用对象就不会拷贝
测试结果
s1对象com.isoftstone.Student@17494c8
s2对象com.isoftstone.Student@e020c9
s1对象年龄:12 s1对象名字:小明 s1对象的引用对象Person:com.isoftstone.Person@888e6c
s2对象年龄:12 s2对象名字:小明 s2对象的引用对象Person:null
transient解释:(by:百度百科)
Java的serialization提供了一种持久化对象实例的机制。当持久化对象时,可能有一个特殊的对象数据成员,我们不想用serialization机制来保存它。为了在一个特定对象的一个域上关闭serialization,可以在这个域前加上关键字transient。当一个对象被序列化的时候,transient型变量的值不包括在序列化的表示中,然而非transient型的变量是被包括进去的。
- java 克隆的浅拷贝与深拷贝
- Java对象克隆——浅拷贝与深拷贝
- java的深拷贝与浅拷贝
- Java的浅拷贝与深拷贝
- java的深拷贝与浅拷贝
- java的深拷贝与浅拷贝
- java的浅拷贝与深拷贝
- Java的深拷贝与浅拷贝
- java的深拷贝与浅拷贝
- JAVA的深拷贝与浅拷贝
- Java对象克隆:浅拷贝和深拷贝
- java对象克隆以及深拷贝和浅拷贝
- Java 拾遗补阙 ----- 浅拷贝和深拷贝(对象克隆)
- java中克隆,浅拷贝,神拷贝
- 克隆、深拷贝和浅拷贝
- <Java>Java数组的深拷贝与浅拷贝
- java中对象的值引用和值拷贝 以及对象的深克隆,浅克隆
- javascript的克隆--深拷贝
- python logging 日志详细配置
- main(int argc, char * argv[])讲解
- MBR损坏修复(二)
- 关于memory warning
- MySQL单表百万数据记录分页性能优化
- java 克隆的浅拷贝与深拷贝
- Asp.net范例:amCharts(.net版)实现图形报表
- 【已解决】:让IE6 IE7 IE8 IE9 IE10 IE11支持Bootstrap
- Discuz门户keywords和description不能正确显示
- BestCoder Round #53 (div.2)(hdu5422,hdu5423,hdu5424)
- 关于C++回调函数设计的思考
- 编写高质量Objective-C代码
- 关于json返回日期格式化的解决方案
- Eclipse Mars Release (4.5.0)下安装编译Spark2.7.1