例:
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) 编辑 收藏