java实现shallow clone(浅克隆)与深克隆(deep clone)
2013-08-30 15:03
507 查看
克隆就是复制一个对象的复本.但一个对象中可能有基本数据类型,如:int,long,float 等,也同时含有非基本数据类型如(数组,集合等)被克隆得到的对象基本类型的值修改了,原对象的值不会改变.这种适合shadow clone(浅克隆).
但如果你要改变一个非基本类型的值时,原对象的值却改变了,.比如一个数组,内存中只copy他的地址,而这个地址指向的值并没有 copy,当clone时,两个地址指向了一个值,这样一旦这个值改变了,原来的值当然也变了,因为他们共用一个值.,这就必须得用深克隆(deep clone)
以下举个例子,说明以上情况.
被克隆类:ShadowClone.java
克隆前: dc1.a=100
克隆前: dc1.b=clone1
克隆前: dc1.c[0]=1000
-----------
克隆前: dc1.a=100
克隆前: dc1.b=clone1
克隆前: dc1.c[0]=1000
-----------
克隆后: dc2.a=50
克隆后: dc2.b=clone2
克隆后: dc2.c[0]=500
深克隆后:修改dc1或者dc2,无论是基本类型还是引用类型,他们的值都不会随着一方改变另一方也改变.
总结:
当克隆的对象只有基本类型,不含引用类型时,可以用浅克隆实现.
当克隆的对象含有引用类型时,必须使用深克隆实现.
但如果你要改变一个非基本类型的值时,原对象的值却改变了,.比如一个数组,内存中只copy他的地址,而这个地址指向的值并没有 copy,当clone时,两个地址指向了一个值,这样一旦这个值改变了,原来的值当然也变了,因为他们共用一个值.,这就必须得用深克隆(deep clone)
以下举个例子,说明以上情况.
被克隆类:ShadowClone.java
public class ShadowClone implements Cloneable { // 基本类型 private int a; // 非基本类型 private String b; // 非基本类型 private int[] c; // 重写Object.clone()方法,并把protected改为public @Override public Object clone() { ShadowClone sc = null; try { sc = (ShadowClone) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return sc; } public int getA() { return a; } public void setA(int a) { this.a = a; } public String getB() { return b; } public void setB(String b) { this.b = b; } public int[] getC() { return c; } public void setC(int[] c) { this.c = c; } }测试类Test.java
import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; public class Test { public static void main(String[] args) throws CloneNotSupportedException { Test t = new Test(); DeepClone dc1 = new DeepClone(); // 对dc1赋值 dc1.setA(100); dc1.setB("clone1"); dc1.setC(new int[] { 1000 }); System.out.println("克隆前: dc1.a=" + dc1.getA()); System.out.println("克隆前: dc1.b=" + dc1.getB()); System.out.println("克隆前: dc1.c[0]=" + dc1.getC()[0]); System.out.println("-----------"); DeepClone dc2 = (DeepClone) t.deepClone(dc1); // 对c2进行修改 dc2.setA(50); dc2.setB("clone2"); int[] a = dc2.getC(); a[0] = 500; dc2.setC(a); System.out.println("克隆前: dc1.a=" + dc1.getA()); System.out.println("克隆前: dc1.b=" + dc1.getB()); System.out.println("克隆前: dc1.c[0]=" + dc1.getC()[0]); System.out.println("-----------"); System.out.println("克隆后: dc2.a=" + dc2.getA()); System.out.println("克隆后: dc2.b=" + dc2.getB()); System.out.println("克隆后: dc2.c[0]=" + dc2.getC()[0]); } // 用序列化与反序列化实现深克隆 public Object deepClone(Object src) { Object o = null; try { if (src != null) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(src); oos.close(); ByteArrayInputStream bais = new ByteArrayInputStream(baos .toByteArray()); ObjectInputStream ois = new ObjectInputStream(bais); o = ois.readObject(); ois.close(); } } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return o; } }结果:
克隆前: dc1.a=100
克隆前: dc1.b=clone1
克隆前: dc1.c[0]=1000
-----------
克隆前: dc1.a=100
克隆前: dc1.b=clone1
克隆前: dc1.c[0]=1000
-----------
克隆后: dc2.a=50
克隆后: dc2.b=clone2
克隆后: dc2.c[0]=500
深克隆后:修改dc1或者dc2,无论是基本类型还是引用类型,他们的值都不会随着一方改变另一方也改变.
总结:
当克隆的对象只有基本类型,不含引用类型时,可以用浅克隆实现.
当克隆的对象含有引用类型时,必须使用深克隆实现.
相关文章推荐
- java实现深克隆(deep clone)
- java实现shadow clone(浅克隆)与深克隆(deep clone)
- java对象 深度克隆(不实现Cloneable接口)和浅度克隆
- Java Cloneable接口与Serializable接口实现对象克隆和深度克隆
- 实现对象深度克隆(deepClone)的三种方案
- JAVA中的深度克隆(deep clone) 和 影子克隆(shallow clone)浅析
- java使用serializable进行序列化与反序列化实现对象clone(克隆)
- Object.clone()方法引申出的浅克隆、深克隆、java原型模式的实现、不可变类的实现
- 数组克隆及对象的深、浅克隆(deep clone、shallow clone)
- Java Deep Clone Shallow Clone 深克隆和浅克隆
- java对象 深度克隆(不实现Cloneable接口)和浅度克隆
- java对象 深度克隆(不实现Cloneable接口)和浅度克隆
- java之实现Cloneable接口的详解,克隆一个对象--对应有浅克隆和深克隆,概念结合代码深入理解
- java shallow clone(浅克隆)与深克隆(deep clone) 笔记
- JAVA 构造器, extends[继承], implements[实现], Interface[接口], reflect[反射], clone[克隆], final, static, abstrac
- java对象 深度克隆(不实现Cloneable接口)和浅度克隆
- Java:浅克隆(shallow clone)与深克隆(deep clone)
- Java Deep Clone Shallow Clone 深克隆和浅克隆
- java 浅层克隆和深层克隆(实现接口Cloneable)
- js面试题:实现对象深度克隆(deepClone)的三种方案