以前也用过这个接口,那时是直接所有的东西都自己写了,也没发现问题。最近无意间发现这个接口的实现并不是想象中的那样,所以稍微研究了下,给大家分享一下。
步骤: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<Student> 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<Student> getList() {
return list;
}
public void setList(List<Student> 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<Student> list = new ArrayList<Student>();
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、对于深复制来说,克隆出来的对象不但跟原始对象不一样(地址不一样),而且内部应用对象也不一样了(地址不一样)