转载 

JAVA 通过字节流实现深克隆实现org.apache.commons.lang3.SerializationUtils

分类:java,整理    749人阅读    IT小君  2021-09-16 21:41

通过 JDK 自带的字节流实现深克隆的方式,是先将要原型对象写入到内存中的字节流,然后再从这个字节流中读出刚刚存储的信息,来作为一个新的对象返回,那么这个新对象和原型对象就不存在任何地址上的共享,这样就实现了深克隆,代码如下

import java.io.*;



public class ThirdExample {

    public static void main(String[] args) throws CloneNotSupportedException {

        // 创建对象

        Address address = new Address(110, "北京");

        People p1 = new People(1, "Java", address);



        // 通过字节流实现克隆

        People p2 = (People) StreamClone.clone(p1);



        // 修改原型对象

        p1.getAddress().setCity("西安");



        // 输出 p1 和 p2 地址信息

        System.out.println("p1:" + p1.getAddress().getCity() +

                " p2:" + p2.getAddress().getCity());

    }



    /**

     * 通过字节流实现克隆

     */

    static class StreamClone {

        public static <T extends Serializable> T clone(People obj) {

            T cloneObj = null;

            try {

                // 写入字节流

                ByteArrayOutputStream bo = new ByteArrayOutputStream();

                ObjectOutputStream oos = new ObjectOutputStream(bo);

                oos.writeObject(obj);

                oos.close();

                // 分配内存,写入原始对象,生成新对象

                ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());//获取上面的输出字节流

                ObjectInputStream oi = new ObjectInputStream(bi);

                // 返回生成的新对象

                cloneObj = (T) oi.readObject();

                oi.close();

            } catch (Exception e) {

                e.printStackTrace();

            }

            return cloneObj;

        }

    }



    /**

     * 用户类

     */

    static class People implements Serializable {

        private Integer id;

        private String name;

        private Address address;

        // 忽略构造方法、set、get 方法

    }



    /**

     * 地址类

     */

    static class Address implements Serializable {

        private Integer id;

        private String city;

        // 忽略构造方法、set、get 方法

    }

}

以上程序的执行结果为:

p1:西安 p2:北京

此方式需要注意的是,由于是通过字节流序列化实现的深克隆,因此每个对象必须能被序列化,必须实现 Serializable 接口,标识自己可以被序列化,否则会抛出异常 (java.io.NotSerializableException)。


使用 Apache Commons Lang 来实现深克隆,实现代码如下:

import org.apache.commons.lang3.SerializationUtils;



import java.io.Serializable;



/**

 * 深克隆实现方式四:通过 apache.commons.lang 实现

 */

public class FourthExample {

    public static void main(String[] args) throws CloneNotSupportedException {

        // 创建对象

        Address address = new Address(110, "北京");

        People p1 = new People(1, "Java", address);



        // 调用 apache.commons.lang 克隆对象

        People p2 = (People) SerializationUtils.clone(p1);



        // 修改原型对象

        p1.getAddress().setCity("西安");



        // 输出 p1 和 p2 地址信息

        System.out.println("p1:" + p1.getAddress().getCity() +

                " p2:" + p2.getAddress().getCity());

    }



    /**

     * 用户类

     */

    static class People implements Serializable {

        private Integer id;

        private String name;

        private Address address;

        // 忽略构造方法、set、get 方法

    }



    /**

     * 地址类

     */

    static class Address implements Serializable {

        private Integer id;

        private String city;

        // 忽略构造方法、set、get 方法

    }

}









支付宝打赏 微信打赏

如果文章对你有帮助,欢迎点击上方按钮打赏作者

 工具推荐 更多»