美文网首页
如何实现对象克隆?

如何实现对象克隆?

作者: majorty | 来源:发表于2020-08-08 22:53 被阅读0次

    有两种方式。
    1.实现 Cloneable 接口并重写 Object 类中的 clone()方法;
    2.实现 Serializable 接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆,代码如下。
    工具类clone()方法:
    注意:基于序列化和反序列化实现的克隆不仅仅是深度克隆,更重要的是通过泛型限定,可以检查出要克隆的对象是否支持序列化,这项检查是编译器完成的,不是在运行时抛出异常,这种是方案明显优于使用Object类的clone方法克隆对象。让问题在编译的时候暴露出来总是好过把问题留到运行时。

    package com.majorty.shiro;
    
    import java.io.Serializable;
    
    /**
     * @author Administrator
     * @description Person
     * @date 2020-08-08 22:33
     * @since JDK 1.8
     */
    
    public class Person implements Serializable {
    
        private static final long serialVersionUID = -9102017020286042305L;
    
        /**
         * 姓名
         */
        private String name;
    
        /**
         * 年龄
         */
        private int age;
    
        /**
         * 座驾
         */
        private Car car;
    
        public Person(String name, int age, Car car) {
            this.name = name;
            this.age = age;
            this.car = car;
        }
    
        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 Car getCar() {
            return car;
        }
    
        public void setCar(Car car) {
            this.car = car;
        }
    
        @Override
        public String toString() {
            return "Person [name=" + name + ", age=" + age + ", car=" + car + "]";
        }
    }
    
    
    
    package com.majorty.shiro;
    
    import java.io.Serializable;
    
    /**
     * 小汽车实体类
     * @author Administrator
     * @date 2020/08/08
     */
    public class Car implements Serializable {
    
        private static final long serialVersionUID = -5713945027627603702L;
    
        /**
         * 品牌
         */
        private String brand;
    
        /**
         * 最高时速
         */
        private int maxSpeed;
    
        public Car(String brand, int maxSpeed) {
            this.brand = brand;
            this.maxSpeed = maxSpeed;
        }
    
        public String getBrand() {
            return brand;
        }
    
        public void setBrand(String brand) {
            this.brand = brand;
        }
    
        public int getMaxSpeed() {
            return maxSpeed;
        }
    
        public void setMaxSpeed(int maxSpeed) {
            this.maxSpeed = maxSpeed;
        }
    
        @Override
        public String toString() {
            return "Car [brand=" + brand + ", maxSpeed=" + maxSpeed + "]";
        }
    }
    
    
    package com.majorty.shiro;
    
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.io.Serializable;
    
    /**
     * 实现 Serializable 接口,通过对象的序列化和反序列化实现深度克隆
     * @author Administrator
     * @date 2020/08/08
     */
    public class MyUtil {
        private MyUtil() {
            throw new AssertionError();
        }
    
        /**
         * 说明:调用 ByteArrayInputStream 或 ByteArrayOutputStream 对象的 close 方法没有任何意义
         * 这两个基于内存的流只要垃圾回收器清理对象就能够释放资源,这一点不同于对外部资源(如文件流)的释放
         * @param obj
         * @param <T>
         * @return
         * @throws Exception
         */
        public static <T extends Serializable> T clone(T obj) throws Exception {
            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();
        }
    }
    
    
    package com.majorty.shiro;
    
    /**
     * 测试类
     * @author Administrator
     * @date 2020/08/08
     */
    public class CloneTest {
        public static void main(String[] args) {
            try {
                Person p1 = new Person("Hao LUO", 33, new Car("Benz", 300));
                // 深度克隆
                Person p2 = MyUtil.clone(p1);
                p2.getCar().setBrand("BYD");
                // 修改克隆的 Person 对象 p2 关联的汽车对象的品牌属性
                // 原来的 Person 对象 p1 关联的汽车不会受到任何影响
                // 因为在克隆 Person 对象时其关联的汽车对象也被克隆了
                System.out.println(p1);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    

    相关文章

      网友评论

          本文标题:如何实现对象克隆?

          本文链接:https://www.haomeiwen.com/subject/woekdktx.html