深浅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指向另一块内存,而不是修改目前所引用的内存