Wayne
井底的蛙--一直仰望着天空
posts - 16,comments - 6,trackbacks - 0

例:
Friend.java
class Friend implements Cloneable {
           int age;
           String name;//           StringBuffer name;
          public Friend(int age, String name) {
           this.age = age;
           this.name = name; 
          }
          
          public Object clone () throws CloneNotSupportedException {
           return super.clone(); 
          }
           
}

Person.java
class Person implements Cloneable  {
           int age;
          /* *
           *String 类型特殊,因为他为引用型,而且他指向的值为常量,克隆出来的对象改变他的值
           *实际上是改变了克隆出来对象String类型成员的指向,不会影响被克隆对象的值及其指向。
          */
           String name;
          
           Friend f;
          
          public Person(int age, String name, Friend f) {
           this.age = age;
           this.name = name;
           this.f = f;
          }
          
          //组合对象的克隆
          public Object clone () throws CloneNotSupportedException {
           Person p = (Person)super.clone(); //需要对每一个成员对象实现clone()
           p.f = (Friend)p.f.clone();
           return p; 
          }
          
          public String toString(){
          StringBuffer sb = new StringBuffer();
          return super.toString()+sb.append("  age=").append(age).
           append(",name=").append(name).
           append("  friend=").append("f.name=").
           append(f.name).append("f.age=").append(f.age).toString();
         }
}

CloneTest.java
import java.util.ArrayList;
import java.util.Iterator;
public class CloneTest {
          public static void main(String [] args)  throws CloneNotSupportedException {
           Person p = new Person(4,"num1",new Friend(5,"haha"));//new StringBuffer("haha")));
           Person p1 = (Person)p.clone();
           p1.name = "new";       //看似类似于基本类型,其实暗藏玄机
           p1.age = 10;
           p1.f.name = "hehe";
           //p1.f.name = new StringBuffer("hehe");//新产生了一个引用,覆给了它
           p1.f.age = 56;
           System.out.println (p);//+"——  age"+p.age +" name "+p.name );
           System.out.println (p1);//+"——  age"+p1.age +" name "+p1.name );
          
          ArrayList testList=new ArrayList();
          testList.add(p);
          testList.add(p1);
          
          System.out.println("befor testList:"+testList);
          
          //ArrayList的克隆
          ArrayList newList=(ArrayList)testList.clone();        
          //要一一走访ArrayList/HashMap所指的每一个对象,并逐一克隆。
          for(int i=0; i<newList.size() ; i++)
                  newList.set(i, ((Person)newList.get(i)).clone());
          for(Iterator e=newList.iterator();e.hasNext();)
                          ((Person)e.next()).age+=1;
          
          System.out.println("after: testList"+testList);
          System.out.println("after: newList"+newList);
          
          }  
          
}


总结

1、基本数据类型能自动实现深度clone
2、String是一个例外。
   但对于我们编程来说可以和操作基本数据类型一样做,基本没影响。大大方便了我们的编程。

   String类型的变量clone后的表现好象也实现了深度clone,但其实只是一个假象。
   因为执行 p1.name = "new";语句时,它作用相当于生成了一个新的string类型,然后又赋回给p1.name。
   这是因为string被sun公司的工程师写成了一个不可更改的类(immutable class),在所有string类中的函数都不能更改自身的值。

==> 这告诉我们支持更方便实现克隆的一种途径:将自己定义的类编写为不可更改。

3、StringBuffer需要做特殊处理
   String和StringBuffer有区别。
   可以借鉴类似技巧对StringBuffer型的变量实现克隆效果:sb=new StringBuffer(sb.toString()); 
posted on 2010-08-28 17:47 waynewan 阅读(832) 评论(0)  编辑  收藏

只有注册用户登录后才能发表评论。


网站导航: