http://blog.youkuaiyun.com/puppylpg/article/details/45706417
http://blog.youkuaiyun.com/centre10/article/details/6847973
上图展示了浅拷贝:对于非基本数据类型,clone过后,结果两个指针指向了同一块儿内存空间,所以仅仅是浅拷贝,这样的话如果对一个对象进行操作,另一个内容也会变,这显然是不合理的,应该每个对象分别保存自己的数据。
所以我们要进行深拷贝!
浅拷贝和深拷贝例子:
Student Construnctor called
stu1'name:Tom
stu2'name:Mary
true
Tom's course: [Java, C#]
Mary's course: [Java, C#]
----- ----- -----I'm cut-off rule----- ----- -----
Student Construnctor called
stu1'name:Tom
stu2'name:Mary
false
Tom's course: [Java]
Mary's course: [C#]
由结果可知,第一种调用浅拷贝导致对Mary添加课程C#的时候,Tom的课程中竟然也有了C#,而且Mary的课程中也有Tom的Java,且stu1.getCourses()==stu2.getCourses()返回的是“true”,说明二者的course属性指向的就是同一块儿内存;而在第二种情况中,我们为copy出来的Mary的course新开辟了一块儿空间cloning.courses = new Vector(),所以Tom和Mary操控的是不同的Vector内存,两者自然就不一样了。
在上例中,深拷贝deepClone()和浅拷贝newInstance()函数都是我们自己写的,所以deepClone()的Student cloning = (Student) super.clone()和Student cloning = (Student) this.clone()都是可行的。除此之外,我们也可以直接覆写本类的clone()函数这样的话就只能使用Student cloning = (Student) super.clone()了,覆写的代码如下:
这里不能使用 Student cloning = (Student) this.clone()的原因是我们正在覆写本类的clone()方法,如果再调用本类的函数,即:this.clone(),就相当于无限递归无限死循环了,最终肯定会崩溃的。所以这里我们只能调用父类的函数,即:super.clone()。
所以,要么自己给自己的深拷贝函数起一个名字,要么覆写本类的clone()方法,自己选一个就好,但两者的关键都在于——对于非基本数据类型,要重新new一块儿空间。