容易发生误用的情况, 类变量是个类情况下,以为只要类变量实现了clone方法,就可以实现类的深拷贝,其实,这个时候也要 在clone方法中对类变量进行clone,否则还是浅拷贝。废话少说,代码如下:
1、没有实现clone的情况
public class Dog { public int legCounts; public Dog(int legCounts) { this.legCounts = legCounts; } public void changeLegCounts() { this.legCounts *= 2; } public String toString() { return Integer.toString(legCounts); } } public class GouClone implements Cloneable { public int legCounts; Dog dog = new Dog(4); protected GouClone clone() throws CloneNotSupportedException { return (GouClone)super.clone(); } } public class Client { public static void main(String[] args) throws CloneNotSupportedException { // TODO Auto-generated method stub GouClone gouClone = new GouClone(); gouClone.legCounts = 3; System.out.println("原拷贝狗腿的数量:" + gouClone.legCounts); System.out.println("原普通狗的数量:" + gouClone.dog); GouClone gouClone1 = (GouClone)gouClone.clone(); gouClone1.legCounts = 2; Dog dog = gouClone1.dog; dog.changeLegCounts(); System.out.println("拷贝后,原来普通狗的数量:" + gouClone.dog); System.out.println("拷贝后,拷贝狗腿的数量:" + gouClone1.legCounts); System.out.println("拷贝后,普通狗的数量:" + gouClone1.dog); } }
结果是:
原拷贝狗腿的数量:3
原普通狗腿的数量:4
拷贝后,原来普通狗的数量:8
拷贝后,拷贝狗腿的数量:2
拷贝后,普通狗的数量:8
2、只实现了clone方法,类变量没有clone
public class Dog implements Cloneable { public int legCounts; public Dog(int legCounts) { this.legCounts = legCounts; } public void changeLegCounts() { this.legCounts *= 2; } public Dog clone() throws CloneNotSupportedException { return (Dog)super.clone(); } public String toString() { return Integer.toString(this.legCounts); } } public class GouClone implements Cloneable { public int legCounts; Dog dog = new Dog(4); protected GouClone clone() throws CloneNotSupportedException { GouClone clone = (GouClone)super.clone(); return clone; } } public class Client { public static void main(String[] args) throws CloneNotSupportedException { // TODO Auto-generated method stub GouClone gouClone = new GouClone(); gouClone.legCounts = 3; System.out.println("原拷贝狗腿的数量:" + gouClone.legCounts); System.out.println("原普通狗的数量:" + gouClone.dog); GouClone gouClone1 = (GouClone)gouClone.clone(); gouClone1.legCounts = 2; Dog dog = gouClone1.dog; dog.changeLegCounts(); System.out.println("拷贝后,原来普通狗的数量:" + gouClone.dog); System.out.println("拷贝后,拷贝狗腿的数量:" + gouClone1.legCounts); System.out.println("拷贝后,普通狗的数量:" + gouClone1.dog); } }
结果是:
原拷贝狗腿的数量:3
原普通狗腿的数量:4
拷贝后,原来普通狗的数量:8
拷贝后,拷贝狗腿的数量:2
拷贝后,普通狗的数量:8
3、类变量也在clone中体现,真正实现深拷贝
public class Dog implements Cloneable { public int legCounts; public Dog(int legCounts) { this.legCounts = legCounts; } public void changeLegCounts() { this.legCounts *= 2; } public Dog clone() throws CloneNotSupportedException { return (Dog)super.clone(); } public String toString() { return Integer.toString(this.legCounts); } } public class GouClone implements Cloneable { public int legCounts; Dog dog = new Dog(4); protected GouClone clone() throws CloneNotSupportedException { GouClone clone = (GouClone)super.clone(); clone.dog = clone.dog.clone(); return clone; } } public class Client { public static void main(String[] args) throws CloneNotSupportedException { // TODO Auto-generated method stub GouClone gouClone = new GouClone(); gouClone.legCounts = 3; System.out.println("原拷贝狗腿的数量:" + gouClone.legCounts); System.out.println("原普通狗的数量:" + gouClone.dog); GouClone gouClone1 = (GouClone)gouClone.clone(); gouClone1.legCounts = 2; Dog dog = gouClone1.dog; dog.changeLegCounts(); System.out.println("拷贝后,原来普通狗的数量:" + gouClone.dog); System.out.println("拷贝后,拷贝狗腿的数量:" + gouClone1.legCounts); System.out.println("拷贝后,普通狗的数量:" + gouClone1.dog); } }
结果是:
原拷贝狗腿的数量:3
原普通狗的数量:4
拷贝后,原来普通狗的数量:4
拷贝后,拷贝狗腿的数量:2
拷贝后,普通狗的数量:8
当然,除了类变量clone在clone()方法中体现,也可以通过引用类实现Serializable接口,并在clone()方法中将对象从流中取出,也是一个办法。