以前也用過這個接口,那時是直接所有的東西都自己寫了,也沒發現問題。最近無意間發現這個接口的實作并不是想象中的那樣,是以稍微研究了下,給大家分享一下。
步驟:1、建立兩個簡單的POJO:Teacher和Student
2、Teacher類實作了Cloneable接口,重寫clone方法
3、在main方法中建立teacher,然後clone,比較teacher和clone出來的teacher
Teacher類:
public class Teacher implements Cloneable,Serializable{
private String name;
private String sex;
private int age;
private List list;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public List getList() {
return list;
}
public void setList(List list) {
this.list = list;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
protected Teacher clone() throws CloneNotSupportedException {
Teacher t = (Teacher)super.clone();
return t;
}
public Teacher deepClone() throws IOException, ClassNotFoundException
{
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream temp_out = new ObjectOutputStream(out);
temp_out.writeObject(this);
ByteArrayInputStream input = new ByteArrayInputStream(out.toByteArray());
ObjectInputStream temp_input = new ObjectInputStream(input);
return (Teacher) temp_input.readObject();
}
}
Student類:
public class Student implements Serializable{
private String stName;
private String stSex;
public String getStName() {
return stName;
}
public void setStName(String stName) {
this.stName = stName;
}
public String getStSex() {
return stSex;
}
public void setStSex(String stSex) {
this.stSex = stSex;
}
}
main:
public class MainTest {
public static void main(String[] args) throws CloneNotSupportedException, ClassNotFoundException, IOException {
List list = new ArrayList();
Student st = new Student();
st.setStName("stname");
st.setStSex("f");
list.add(st);
Teacher te = new Teacher();
te.setAge(19);
te.setList(list);
te.setName("tename");
te.setSex("tesex");
Teacher cl = te.clone();
cl.setAge(12);
System.out.println("淺複製"+ (cl == te));
//記憶體中的位址
System.out.println(cl.getName() == te.getName());
System.out.println(cl.getList() == te.getList());
System.out.println("source:"+te.getAge()+"<==>clone:"+cl.getAge());
Teacher deep = te.deepClone();
System.out.println("深複製"+(cl == te));
System.out.println(deep.getName() == te.getName());
System.out.println(deep.getList() == te.getList());
}
}
輸出結果:
淺複製false
true
true
source:19<==>clone:12
深複製false
false
false
從輸出結果可以得出的結論:
1、對于淺複制來說,當調用clone方法傳回的cl對象跟te對象不是同一個對象(位址不一樣),但是内部的對象引用卻是引用的相同對象(位址一樣);而對于基本類型age(int)來說,克隆的對象cl跟原始對象te不是同一個(如果是同一個的話,修改任何一個,另外對象的内容也會變化)
2、對于深複制來說,克隆出來的對象不但跟原始對象不一樣(位址不一樣),而且内部應用對象也不一樣了(位址不一樣)