java原形模式(clone)之疑惑?

java原型模式(clone)之疑惑???

      近期在javaeye看到一位兄弟写的java原型模式之理解。然后,自己就写了个demo,但是在使用colone时,好像出现了些问题??

 

定义如下几个类:

 

public class BtripApplication implements Cloneable{
 
   private int a;

public int getA() {
 return a;
}

public void setA(int a) {
 this.a = a;
}
  
public BtripApplication clone() throws CloneNotSupportedException {
 return (BtripApplication)super.clone();
}
}

------------------------------------------------

 

public class BtripRevision implements Cloneable {
 
  private BtripApplication btripApplication;
 
  public BtripRevision(BtripApplication btripApplication){
   this.btripApplication =  btripApplication;
  }
 
public BtripApplication getBtripApplication() {
 return btripApplication;
}
public void setBtripApplication(BtripApplication btripApplication) {
 this.btripApplication = btripApplication;
}

public BtripRevision clone() throws CloneNotSupportedException {
 return (BtripRevision)super.clone();
}
}

---------------------------------------------

public class TestBtripApplicationRevision {
  public static void main(String args[]) throws CloneNotSupportedException{
   BtripApplication b1 = new BtripApplication();
   b1.setA(1);
   BtripRevision b2 = new BtripRevision(b1);
   BtripRevision b3 =  b2.clone();
   //b3.getBtripApplication().setA(3);
   b1.setA(3);
   System.out.println("b2="+b2.getBtripApplication().getA());
   System.out.println("b3="+b3.getBtripApplication().getA());
   System.out.println("b2="+b2+"--------b3="+b3);
  }
}

 

输出的结果为:b2=3
                    b3=3

为什么结果不是b2=1,b3=3呢???

1 楼 mercyblitz 2010-06-25  
引用
   BtripRevision b2 = new BtripRevision(b1);

引用
b1.setA(3);


传递了b1对象引用,哪么b1也会相应的变化。
2 楼 tigers20010 2010-06-25  
mercyblitz 写道
引用
   BtripRevision b2 = new BtripRevision(b1);

引用
b1.setA(3);


传递了b1对象引用,哪么b1也会相应的变化。


在调用b2.clone()时,没有调用b1的clone方法???也就是说,在调b2.clone()时,必然要进行b1的copy,难道b1没有进行深拷贝??java原形模式(clone)之疑惑?
3 楼 mercyblitz 2010-06-25  
tigers20010 写道
mercyblitz 写道
引用
   BtripRevision b2 = new BtripRevision(b1);

引用
b1.setA(3);


传递了b1对象引用,哪么b1也会相应的变化。


在调用b2.clone()时,没有调用b1的clone方法???也就是说,在调b2.clone()时,必然要进行b1的copy,难道b1没有进行深拷贝??java原形模式(clone)之疑惑?



恩,这个时候b2和b3引用了同一个b1。

clone并没有深入下去。没有生成一个新的b1。
4 楼 tigers20010 2010-06-25  
mercyblitz 写道
tigers20010 写道
mercyblitz 写道
引用
   BtripRevision b2 = new BtripRevision(b1);

引用
b1.setA(3);


传递了b1对象引用,哪么b1也会相应的变化。


在调用b2.clone()时,没有调用b1的clone方法???也就是说,在调b2.clone()时,必然要进行b1的copy,难道b1没有进行深拷贝??java原形模式(clone)之疑惑?



恩,这个时候b2和b3引用了同一个b1。

clone并没有深入下去。没有生成一个新的b1。


现在我想b2.clone()时,b1也要进行深拷贝?(项目中有这种类似的需求,当时我是在每个modle里,写了个selfcopy()的方法,进行一一赋值的,想想真够麻烦的)。后来我将public BtripRevision clone() throws CloneNotSupportedException {
return (BtripRevision)super.clone();
}
改为public BtripRevision clone() throws CloneNotSupportedException {
  btripApplication.clone();
return (BtripRevision)super.clone();
}也不行啊,不知道是为何?感觉那位老兄讲的原型模式,不是太清楚额?
5 楼 z276356445t 2010-12-13  
刚刚我也看了下这个原型设计模式,就你目前的情况来看,你是用的浅拷贝吧,如果要深拷贝的话,你的成员变量必须也要重新拷贝一个,然而在你客户端进行引用的时候只能对你拷贝的对象进行赋值才能达到你理想的结果,你可以这样改.
public BtripRevision clone() throws CloneNotSupportedException {
this.btripApplication = (BtripApplication)this.btripApplication.clone();
return (BtripRevision) super.clone();
}

客户端应该这样去访问:
public static void main(String args[]) throws CloneNotSupportedException {
BtripApplication b1 = new BtripApplication();
b1.setA(1);
BtripRevision b2 = new BtripRevision(b1);
BtripRevision b3 = b2.clone();
// b3.getBtripApplication().setA(3);
b1.setA(3);
b3.setBtripApplication(b1);
System.out.println("b2=" + b2.getBtripApplication().getA());
System.out.println("b3=" + b3.getBtripApplication().getA());
System.out.println("b2=" + b2 + "--------b3=" + b3);
}