java中的复制分为淺复制和深复制,淺复制只是复制一些基本的数据类型,而对象还是同一个引用。深复制是一种彻底的复制,
包括对象里面的对象对会完全复制,就例如有一个房子类A,房子里面有家居类,汽车类等等,如果B淺复制了A,那么B里面的家居类,汽车类都只是A对象里面的引用,但是如果是深复制的话,则是复制了一份新的到B中。
下面通过一个我写的实例来了解这个过程:
- public class JavaClone {
- //A是B中的一个类变量
- public static class A implements Cloneable{
- int num = 1;
- public void setNum(int num){
- this.num = num;
- }
- //将数值翻倍
- public void doubleNum(){
- num*=2;
- }
- public A(int num){
- this.num = num;
- }
- @Override
- public Object clone(){
- A a = null;
- try {
- a = (A) super.clone();
- } catch (CloneNotSupportedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- return a;
- }
- }
- //B中含有基本变量和类变量
- public static class B implements Cloneable{ //实现克隆功能的类都要实现这个接口,否则就会抛出CloneNotSupporteException
- public int num = 1;
- A a = new A(100);
- public void setNum(int num){
- this.num = num;
- }
-
- @Override
- public Object clone(){
- B o = null;
- try {
- o = (B)super.clone();
- } catch (CloneNotSupportedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- o.a = (A)o.a.clone(); //对B中的a也进行复制,如果a对象中还有其他的对象要复制,那么对应的a中的clone方法就要克隆相应的类
- return o;
-
- }
- }
-
- /**
- * @param args
- */
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- // JavaClone j = new JavaClone();
- // B b = j.new B();
- B b = new JavaClone.B();
- System.out.println("未克隆之前 B 里面的值");
- System.out.println("B.num:"+b.num+" B.a.num"+b.a.num);
-
- B c = (B) b.clone();
- System.out.println("克隆C C里面的值");
- System.out.println("c.num:"+c.num+" c.a.num"+c.a.num);
-
- System.out.println("将C里面对象a的值加倍后");
- //深度克隆之后,即使c中的对象中的元素改变,也不会改变b中对象对应的值
- b.setNum(2); // 无论是深复制还是淺复制,基本数据类型的改变不会影响其他的克隆对象的基本数据类型的数据
- c.a.doubleNum();
- System.out.println(" B 里面的值");
- System.out.println("B.num:"+b.num+" B.a.num"+b.a.num);
- System.out.println("C里面的值");
- System.out.println("c.num:"+c.num+" c.a.num"+c.a.num);
-
- }
- }
运行结果如下:
未克隆之前 B 里面的值
B.num:1 B.a.num100
克隆C C里面的值
c.num:1 c.a.num100
将C里面对象a的值加倍后
B 里面的值
B.num:2 B.a.num100
C里面的值
c.num:1 c.a.num200
可以看出,对象c 实现了对对象b的克隆,当c中的a对象中的数值加倍之后并不影响b对象中的a对象的值。即b中的a对象和c中的a对象是不同的对象。
但是,如果你把B类中的克隆函数去掉,即下面这一句
o.a = (A)o.a.clone(); //对B中的a也进行复制,如果a对象中还有其他的对象要复制,那么对应的a中的clone方法就要克隆相应的类那么克隆的时候,其实b和c对象中的a对象是同一个对象来的,对b中的a对象的任何改变都会影响到c中的a对象,这是我们所不愿看到的。
阅读(3008) | 评论(0) | 转发(0) |