zoukankan      html  css  js  c++  java
  • string 在clone()中的特殊性 (转载)

     
    http://blog.sina.com.cn/s/blog_5377b40a010007rz.html
    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());

  • 相关阅读:
    jQuery 淡入淡出
    (Windows窗体)循环动态绑定根节点及子节点
    C# 语音读取
    js禁用&启用某个按钮
    AWS DescribeDBInstances API 无法查询到 DBInstanceArn 参数
    Python 设置S3文件属性中元数据的Content-Encoding值
    Pyhton 批量重命名 AWS S3 中的文件
    Python 控制(SSM)AWS Systems Manager
    Python 根据AWS EC2设置的标签获取正在运行的instancesId
    python 'wb' 模式写入文件怎么输出回车
  • 原文地址:https://www.cnblogs.com/carbs/p/2564373.html
Copyright © 2011-2022 走看看