天天看點

java cloneable_java.lang.Cloneable的了解

以前也用過這個接口,那時是直接所有的東西都自己寫了,也沒發現問題。最近無意間發現這個接口的實作并不是想象中的那樣,是以稍微研究了下,給大家分享一下。

步驟: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、對于深複制來說,克隆出來的對象不但跟原始對象不一樣(位址不一樣),而且内部應用對象也不一樣了(位址不一樣)