Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1145445
  • 博文数量: 103
  • 博客积分: 1897
  • 博客等级: 上尉
  • 技术积分: 1717
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-19 21:02
文章分类

全部博文(103)

文章存档

2013年(19)

2012年(84)

分类: Java

2012-05-04 15:26:17

 java中的复制分为淺复制和深复制,淺复制只是复制一些基本的数据类型,而对象还是同一个引用。深复制是一种彻底的复制,
包括对象里面的对象对会完全复制,就例如有一个房子类A,房子里面有家居类,汽车类等等,如果B淺复制了A,那么B里面的家居类,汽车类都只是A对象里面的引用,但是如果是深复制的话,则是复制了一份新的到B中。
下面通过一个我写的实例来了解这个过程:

点击(此处)折叠或打开

  1. public class JavaClone {

  2.     //A是B中的一个类变量
  3.     public static class A implements Cloneable{
  4.         int num = 1;
  5.         public void setNum(int num){
  6.             this.num = num;
  7.         }
  8.         //将数值翻倍
  9.         public void doubleNum(){
  10.             num*=2;
  11.         }
  12.         public A(int num){
  13.             this.num = num;
  14.         }
  15.         @Override
  16.         public Object clone(){
  17.             A a = null;
  18.             try {
  19.                 a = (A) super.clone();
  20.             } catch (CloneNotSupportedException e) {
  21.                 // TODO Auto-generated catch block
  22.                 e.printStackTrace();
  23.             }
  24.             return a;
  25.         }
  26.     }
  27.     //B中含有基本变量和类变量
  28.     public static class B implements Cloneable{ //实现克隆功能的类都要实现这个接口,否则就会抛出CloneNotSupporteException
  29.     public    int num = 1;
  30.         A a = new A(100);
  31.         public void setNum(int num){
  32.             this.num = num;
  33.         }
  34.     
  35.         @Override
  36.         public Object clone(){
  37.         B o = null;
  38.         try {
  39.             o = (B)super.clone();
  40.         } catch (CloneNotSupportedException e) {
  41.             // TODO Auto-generated catch block
  42.             e.printStackTrace();
  43.         }
  44.         o.a = (A)o.a.clone(); //对B中的a也进行复制,如果a对象中还有其他的对象要复制,那么对应的a中的clone方法就要克隆相应的类
  45.             return o;
  46.             
  47.         }
  48.     }
  49.     
  50.     /**
  51.      * @param args
  52.      */
  53.     public static void main(String[] args) {
  54.         // TODO Auto-generated method stub
  55. //        JavaClone j = new JavaClone();
  56. //        B b = j.new B();
  57.         B b = new JavaClone.B();
  58.         System.out.println("未克隆之前 B 里面的值");
  59.         System.out.println("B.num:"+b.num+" B.a.num"+b.a.num);
  60.         
  61.         B c = (B) b.clone();
  62.         System.out.println("克隆C C里面的值");
  63.         System.out.println("c.num:"+c.num+" c.a.num"+c.a.num);
  64.         
  65.         System.out.println("将C里面对象a的值加倍后");
  66.         //深度克隆之后,即使c中的对象中的元素改变,也不会改变b中对象对应的值
  67.         b.setNum(2); // 无论是深复制还是淺复制,基本数据类型的改变不会影响其他的克隆对象的基本数据类型的数据
  68.         c.a.doubleNum();
  69.         System.out.println(" B 里面的值");
  70.         System.out.println("B.num:"+b.num+" B.a.num"+b.a.num);
  71.         System.out.println("C里面的值");
  72.         System.out.println("c.num:"+c.num+" c.a.num"+c.a.num);
  73.         

  74.     }

  75. }

运行结果如下:
未克隆之前 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对象,这是我们所不愿看到的。

阅读(3004) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~