深浅复制及序列化

实现Cloneable接口的clone() 即可实现对象克隆,实现Serializable接口可使对象支持序列化,网上查了下相关资料,clone针对基本类型属性没有问题,但对引用类型时默认只能浅复制,复制的是引用的地址,实现深复制时比较麻烦。自己做了个练习小试一番。

public class TestClone {
/**
 * 浅复制简单对象(仅包含基本类型属性)
 */
@Test
public void shallowCloneSimpleObject() {
    Domain da = new Domain(2, "Zhangsan");
    try {
        Object db = da.clone();
        System.out.println(da.toString());
        System.out.println(db.toString());
    } catch (CloneNotSupportedException e) {
        e.printStackTrace();
    }

    /**
     * 打印结果:
     *          obj.age=2,obj.name.hashCode=-1367991180,obj.hashCode=11352996
                obj.age=2,obj.name.hashCode=-1367991180,obj.hashCode=19313225
            结果分析:
                                   基本类型Clone(克隆)没问题。
     */
}

/**
 * 浅复制复杂对象(包含引用类型属性)
 */
@Test
public void shallowCloneComplexObject() {
    DomainW da = new DomainW();
    try {
        Object db = da.clone();
        System.out.println(da.toString());
        System.out.println(db.toString());
    } catch (CloneNotSupportedException e) {
        e.printStackTrace();
    }

    /**
     * 打印结果:
     *          obj.domain.hashCode=11352996
                obj.domain.hashCode=11352996
            结果分析
                                   基本类型Clone(克隆)没问题,但引用类型Clone的是引用的地址。
     */
}

/**
 * 深复制对象
 */
@Test
public void deepClone() {
    DomainX da = new DomainX();
    try {
        Object db = da.clone();
        System.out.println(da.toString());
        System.out.println(db.toString());
    } catch (CloneNotSupportedException e) {
        e.printStackTrace();
    }
    /**
     * 打印结果:
     *          obj.domain.hashCode=19313225
                obj.domain.hashCode=25358555
            结果分析:
                Clone复杂对象,对引用类型的属性需要再次Clone或实例化。
     */
}

/**
 * 序列化/反序列化复制对象
 */
@Test
public void serializeClone() {
    DomainY da = new DomainY();
    ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
    try {
        /**序列化对象             BEGIN*/
        ObjectOutputStream objOs = new ObjectOutputStream(byteOut);
        objOs.writeObject(da);
        /**序列化对象                  END*/

        /**反序列化对象        BEGIN*/
        ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
        ObjectInputStream objIs = new ObjectInputStream(byteIn);
        Object db = objIs.readObject();
        /**反序列化对象             END*/
        System.out.println(da.toString());
        System.out.println(db.toString());
    } catch (IOException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    /**
     * 打印结果:
     *          obj.domain.hashCode=23065739
                obj.domain.hashCode=12115735
            结果分析:
                利用序列化机制可以实现复杂对象的深复制。
     */

}
}

/**
 * 测试浅复制实体
 *         实现Cloneable和Serializable接口
 */
class Domain implements Cloneable,Serializable{

    private static final long serialVersionUID = -582678566899393941L;
    private int age;
    private String name;

    public Domain() {

    }

    public Domain(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    @Override
    public String toString() {
        return "obj.age="+this.getAge()+",obj.name.hashCode="+this.name.hashCode()+",obj.hashCode="+this.hashCode();
    }
}

/**
 * 测试深复制实体
 *         实现Cloneable接口
 */
class DomainW implements Cloneable{

    private Domain domain = new Domain();


    public DomainW() {

    }

    public Domain getDomain() {
        return domain;
    }

    public void setDomain(Domain domain) {
        this.domain = domain;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    @Override
    public String toString() {
        return "obj.domain.hashCode="+this.domain.hashCode();
    }
}

/**
 * 测试深复制实体
 *         实现Cloneable接口
 */
class DomainX implements Cloneable{

    private Domain domain = new Domain();


    public DomainX() {

    }

    public Domain getDomain() {
        return domain;
    }

    public void setDomain(Domain domain) {
        this.domain = domain;
    }

    protected Object clone() throws CloneNotSupportedException {
        DomainX clone = (DomainX) super.clone();
        clone.setDomain((Domain)clone.getDomain().clone());
        //clone.setDomain(new Domain());
        return clone;
    }

    @Override
    public String toString() {
        return "obj.domain.hashCode="+this.domain.hashCode();
    }
}

/**
 * 测试序列化实现深复制实体
 *         实现Cloneable和Serializable接口
 */
class DomainY implements Serializable{
    private static final long serialVersionUID = 7360119346665988338L;
    private Domain domain = new Domain();

    public DomainY() {

    }

    public Domain getDomain() {
        return domain;
    }

    public void setDomain(Domain domain) {
        this.domain = domain;
    }

    @Override
    public String toString() {
        return "obj.domain.hashCode="+this.domain.hashCode();
    }
}

你可能感兴趣的:(反序列化,序列化,clone)