当前位置: 代码迷 >> J2SE >> 深浅clone有关问题
  详细解决方案

深浅clone有关问题

热度:41   发布时间:2016-04-24 14:10:57.0
深浅clone问题
package   test;

public   class   CloneTest1   implements   Cloneable   {

java.util.Date   date;
String   s   =   "abc ";
public   Object   clone()   {
try   {
return   super.clone();
}   catch   (CloneNotSupportedException   ex)   {

return   null;
}
}

public   static   void   main(String[]   args){
CloneTest1   src=new   CloneTest1();  
CloneTest1   des=(CloneTest1)src.clone();  
System.out.println(src.s);
System.out.println(des.s);
des.s   =   "dddddddd ";
System.out.println(src.s);
System.out.println(des.s);

}
}
为什么输入为
abc
abc
abc
dddddddd
浅clone指向同一个引用,为什么不是
abc
abc
dddddddd
dddddddd


------解决方案--------------------
就应该是这个样子。
浅clone指向同一个引用指:
Class A {
String s = "abc ";
}
Class B {
A a = new A();
}

当你clone一个B的对象的时候,clone后的对象和原对象的a指向同一个引用。
------解决方案--------------------
import java.util.*;
public class CloneTest1 implements Cloneable {

java.util.Date date;
String s = "abc ";
int a[] = new int[]{1,2,3};

public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException ex) {

return null;
}
}

public static void main(String[] args) {
CloneTest1 src = new CloneTest1();
CloneTest1 des = (CloneTest1) src.clone();
System.out.println(Arrays.toString(src.a));
System.out.println(Arrays.toString(des.a));
des.a[2]=1111;
System.out.println(Arrays.toString(src.a));
System.out.println(Arrays.toString(des.a));

}
}
------解决方案--------------------
楼主要理解引用的意思
des.s = "dddddddd ";你这样的话只是改变des.s的引用,但是src.s的引用不会改变,src.s引用的那块内存不会改变,你要做的应该是修改所引用的内存的值,而不是重新去引用一块新的内存

//1
//des.s-> memory1( "abc ")
//src.s-> memory1( "abc ")

//2
des.s = "dddddddd ";
src.s-> memory1( "abc ")
des.s-> memory2( "dddddddd ")
//两个引用互不影响,这时是两块内存空间了


你再改成下面的试试看
package clone;

public class CloneTest1 implements Cloneable {

java.util.Date date;
StringBuffer s = new StringBuffer( "abc ");
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException ex) {

return null;
}
}

public static void main(String[] args){
CloneTest1 src=new CloneTest1();
CloneTest1 des=(CloneTest1)src.clone();
System.out.println(src.s);
System.out.println(des.s);
des.s.append( "_append ");//这个不会改变引用,StringBuffer的append是在原来基础上修改
System.out.println(src.s);
System.out.println(des.s);

}
}


//另外,做这种测试的时候,建议不要用String,这是一个特殊的类,每次都会产生新的引用,容易误导
------解决方案--------------------
改变的是引用变量本身,而不是改变引用对像的值
------解决方案--------------------
跟String一样理解
------解决方案--------------------
des.s =2;

这个都是把s指向另一块内存,而不是修改目前所引用的内存
  相关解决方案