深浅克隆

开过过程中,有时一些对象在逻辑操作中可能值被修改,但是后续操作可能还需要用到没有改变之前的对象,对于这种情况可以使用clone方法来克隆一个相同的对象以便支持后续使用;

⑴浅复制(浅克隆) 

    被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。

⑵深复制(深克隆) 

    被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。

 
 
浅克隆:
package com.osc.demo;
 
import java.util.List;
 
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
 
public class Teacher implements Cloneable {
    private String name;
    private int age;
    private List<Student> student;
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public int getAge() {
        return age;
    }
 
    public void setAge(int age) {
        this.age = age;
    }
 
    public List<Student> getStudent() {
        return student;
    }
 
    public void setStudent(List<Student> student) {
        this.student = student;
    }
 
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
 
    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
    }
}
package com.osc.demo;
 
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
 
public class Student {
    private String name;
    private int age;
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public int getAge() {
        return age;
    }
 
    public void setAge(int age) {
        this.age = age;
    }
 
    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
    }
}

 

package com.osc.demo;
 
import java.util.ArrayList;
import java.util.List;
 
public class Test {
    public static void main(String[] args) {
        Student student = new Student();
        student.setName("张柏芝");
        student.setAge(34);
        List<Student> list = new ArrayList<Student>();
        list.add(student);
        Teacher teacher = new Teacher();
        teacher.setName("陈冠希");
        teacher.setAge(33);
        teacher.setStudent(list);
 
        try {
            Teacher cloneTeacher = (Teacher) teacher.clone();
            System.out.println("修改前teacher:" + teacher);
            System.out.println("修改前cloneTeacher:" + cloneTeacher);
            System.out.println("--modify--");
            student.setName("钟欣桐");
            student.setAge(33);
            System.out.println("修改后teacher:" + teacher);
            System.out.println("修改后cloneTeacher:" + cloneTeacher);
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

--

修改前teacher:Teacher[name=陈冠希,age=33,student=[Student[name=张柏芝,age=34]]]
修改前cloneTeacher:Teacher[name=陈冠希,age=33,student=[Student[name=张柏芝,age=34]]]
--modify--
修改后teacher:Teacher[name=陈冠希,age=33,student=[Student[name=钟欣桐,age=33]]]
修改后cloneTeacher:Teacher[name=陈冠希,age=33,student=[Student[name=钟欣桐,age=33]]]

-------

使用SerializationUtils.clone(obj)重写clone()实现深克隆,利用Serializable进行深拷贝的时候成员属性也必须是Serializable的,否则只返回一个引用

深克隆:

package com.osc.demo;
 
import java.io.Serializable;
import java.util.List;
 
import org.apache.commons.lang.SerializationUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
 
@SuppressWarnings("serial")
public class Teacher implements Cloneable, Serializable {
    private String name;
    private int age;
    private List<Student> student;
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public int getAge() {
        return age;
    }
 
    public void setAge(int age) {
        this.age = age;
    }
 
    public List<Student> getStudent() {
        return student;
    }
 
    public void setStudent(List<Student> student) {
        this.student = student;
    }
 
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return SerializationUtils.clone(this);
    }
 
    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
    }
}
package com.osc.demo;
 
import java.io.Serializable;
 
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
 
@SuppressWarnings("serial")
public class Student implements Serializable {
    private String name;
    private int age;
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public int getAge() {
        return age;
    }
 
    public void setAge(int age) {
        this.age = age;
    }
 
    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
    }
}
package com.osc.demo;
 
import java.util.ArrayList;
import java.util.List;
 
public class Test {
    public static void main(String[] args) {
        Student student = new Student();
        student.setName("张柏芝");
        student.setAge(34);
        List<Student> list = new ArrayList<Student>();
        list.add(student);
        Teacher teacher = new Teacher();
        teacher.setName("陈冠希");
        teacher.setAge(33);
        teacher.setStudent(list);
 
        try {
            Teacher cloneTeacher = (Teacher) teacher.clone();
            System.out.println("修改前teacher:" + teacher);
            System.out.println("修改前cloneTeacher:" + cloneTeacher);
            System.out.println("--modify--");
            student.setName("钟欣桐");
            student.setAge(33);
            System.out.println("修改后teacher:" + teacher);
            System.out.println("修改后cloneTeacher:" + cloneTeacher);
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

--

修改前teacher:Teacher[name=陈冠希,age=33,student=[Student[name=张柏芝,age=34]]]
修改前cloneTeacher:Teacher[name=陈冠希,age=33,student=[Student[name=张柏芝,age=34]]]
--modify--
修改后teacher:Teacher[name=陈冠希,age=33,student=[Student[name=钟欣桐,age=33]]]
修改后cloneTeacher:Teacher[name=陈冠希,age=33,student=[Student[name=张柏芝,age=34]]]

posted @ 2017-12-15 16:24  北境  阅读(229)  评论(1编辑  收藏  举报