本文共 3969 字,大约阅读时间需要 13 分钟。
对于基本数据类型而言,即如下八种基本数据类型,int,boolean,char,byte,short,float,double,long。
1 public classtest2 {3 public static voidmain(String[] args)4 {5 int a=3;6 int b=a;7 int c=3;8 b=2;9 System.out.println("a: "+a);10 System.out.println("b: "+b);11 System.out.println(a==b);12 System.out.println(a==c);13
14 }15 }
说明:对于基本数据类型,==只是比较两个变量的值,并没有比较其地址,并且其变量复制后,任意改变其中一个变量时,并没有对另一个变量产生变化,默认实现的是深拷贝。
一个简单的浅拷贝示例,浅拷贝中复制出来的对象的域与原始对象的域使用相同的对象引用,指向的是同一个对象,相当于在两个对象中对同一个对象进行处理,会产生潜在的问题。
Object类的clone方法复制对象的做法是对当前对象中所有实例域进行逐一复制。先创建一个新的对象,再把新对象中所有的实例域的值初始化成原始对象中对应域的当前值。
1 class ToBeCloned implements Cloneable//Cloneable为标记接口,其内不包含任何方法,要实现此接口的话,必须重写clone方法,否则2 //抛出异常java.lang.CloneNotSupportedException异常
3 {4 private int value=0;5 public void setValue(intvalue)6 {7 this.value=value;8 }9 public intgetValue()10 {11 return this.value;12 }13 publicObject clone()14 {15 try
16 {17 return super.clone();18 }19 catch(CloneNotSupportedException e)20 {21 throw newError(e);22 }23 }24 }25
26
27 public classSimpleClone28 {29 public static voidmain(String[] args)30 {31 ToBeCloned obj=newToBeCloned();32 obj.setValue(1);33 ToBeCloned cloneObj=(ToBeCloned)obj.clone();34
35 System.out.println("cloneObj.getValue(): "+cloneObj.getValue());36 System.out.println("obj.getValue(): "+obj.getValue());37 obj.setValue(2);38 System.out.println("cloneObj.getValue(): "+cloneObj.getValue());39 System.out.println("obj.getValue(): "+obj.getValue());40 }41 }
如果对象中只包含值为基本类型或不可变对象的域,用上面的方法就可以了,内部域为基本数据类型。但是当对象中某些域的值为可变对象时,上述方法就不能满足了。示例如下:
1 classCounter2 {3 private int value=0;4 public voidincrease()5 {6 value++;7 }8 public intgetValue()9 {10 returnvalue;11 }12 }13
14 class MutableObject implementsCloneable15 {16 private Counter counter=newCounter();17 public voidincrease()18 {19 counter.increase();20 }21 public intgetValue()22 {23 returncounter.getValue();24 }25 publicObject clone()26 {27 try
28 {29 return super.clone();30 }31 catch(CloneNotSupportedException e)32 {33 throw newError(e);34 }35 }36 }37
38
39 public classMutableObjectClone40 {41 public static voidmain(String[] args)42 {43 MutableObject obj=newMutableObject();44 obj.increase();45 MutableObject clonedObj=(MutableObject)obj.clone();46 clonedObj.increase();47 obj.increase();48 System.out.println(clonedObj.getValue());49 System.out.println(obj.getValue());50 }51 }
这说明Object类的clone方法已经对类中的基本类型和不可变对象的域进行了处理,只要在这基础上添加对可变对象的域的处理即可。即通过递归的方式来对clone进行修改。
因为在Counter中value为int类型,故递归截止为此函数。
1 class Counter implementsCloneable2 {3 private int value=0;4 public voidincrease()5 {6 value++;7 }8 public intgetValue()9 {10 returnvalue;11 }12 publicObject clone()13 {14 try
15 {16 return super.clone();17 }18 catch(CloneNotSupportedException e)19 {20 throw newError(e);21 }22 }23 }24
25 class MutableObject implementsCloneable26 {27 private Counter counter=newCounter();28 public voidincrease()29 {30 counter.increase();31 }32 public intgetValue()33 {34 returncounter.getValue();35 }36 publicObject clone()37 {38 MutableObject obj;39 try
40 {41 obj=(MutableObject)super.clone();42 obj.counter=(Counter)counter.clone();43 returnobj;44 }45 catch(CloneNotSupportedException e)46 {47 throw newError(e);48 }49 }50 }51
52
53 public classMutableObjectClone54 {55 public static voidmain(String[] args)56 {57 MutableObject obj=newMutableObject();58 obj.increase();59 MutableObject clonedObj=(MutableObject)obj.clone();60 clonedObj.increase();61 obj.increase();62 obj.increase();63 System.out.println("clonedObj.getValue(): "+clonedObj.getValue());64 System.out.println("obj.getValue(): "+obj.getValue());65 }66 }
在这里要注意在类Object中,clone()方法是protected权限的。
进行复制对象的另外一个做法是使用复制构造方法,即用一个已有 的对象去构造另外一个对象。
示例如下:
1 public classUserException2 {3 privateString name;4 privateString email;5
6 publicUser(String name,String email)7 {8 this.name=name;9 this.email=email;10 }11 publicUser(User user)12 {13 this.name=user.getName();14 this.email=user.getEmail();15 }16
17 publicString getName()18 {19 return this.name;20 }21 publicString getEmail()22 {23 return this.email;24 }25 }
转载地址:http://roydy.baihongyu.com/