实现对象克隆:clone()法和序列化反序列化克隆法

克隆方法①:

实现Object类的clone方法,只能进行浅拷贝,如果拷贝失败可能会在运行时抛出异常

import java.io.Serializable;
import java.util.Arrays;

/**
 * ClassName: UsersEntity
 * Description: Object类的clone方法
 * ①实现Cloneable接口
 * ②重写clone方法
 * 浅拷贝绝对正确,但是在面对一些复杂类型的属性时候,可能无法进行深拷贝
 * 要实现真正的深拷贝,需要根据特定的实体类类型去做,我还无法深刻理解,所以这里就不列出了
 *
 * 这里还实现了Serializable接口时为了演示另一种克隆方法
 */
public class UsersEntity implements Cloneable,Serializable{
    int age;
    int[] number;

    public UsersEntity(int age, int[] number) {
        this.age = age;
        this.number = number;
    }

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

    @Override
    public String toString() {
        return "UsersEntity{" +
                "age=" + age +
                ", number=" + Arrays.toString(number) +
                '}';
    }
}

克隆方法②

基于序列化和反序列化实现的不仅仅是深度克隆,更重要的是通过泛型限定,可以检查出要克隆的对象是否支持序列化

这项检查是在编译器完成的,不是运行时抛出异常,优于方法①,让问题再编译的时候暴露出来比运行时抛出好

import java.io.*;

/**
 * ClassName: CloneUtil
 */
public class CloneUtil {

    /**
     * 实现对象克隆方法
     * 1)实体类实现Cloneable接口并重写Object类的clone()方法
     * 2)实体类实现Serializable接口,Serializable接口没有任何抽象方法,只是起到一个标记作用
     *   使得实体类能够被序列号,然后通过对象的序列化和反序列化进行克隆
     */
    public static  T clone(T obj) throws IOException, ClassNotFoundException {
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bout);
        oos.writeObject(obj);

        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bin);

        return (T) ois.readObject();
    }
}

测试类

public class TestClone {

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        int[] number = {5,3,56};
        int age = 123;

        // 克隆方法①:实现Object类的clone方法,只能进行浅拷贝,如果拷贝失败可能会在运行时抛出异常
        UsersEntity users = new UsersEntity(age,number);
        System.out.println(users);

        // 克隆方法②:基于序列化和反序列化实现的不仅仅是深度克隆,更重要的是通过泛型限定,可以检查出要克隆的对象是否支持序列化
        // 这项检查是在编译器完成的,不是运行时抛出异常,优于方法①,让问题再编译的时候暴露出来比运行时抛出好
        UsersEntity usersClone = CloneUtil.clone(users);
        System.out.println(usersClone);
    }
}

 

你可能感兴趣的:(EffectiveJava)