• 创建者模式 -- 原型模式


    以某个对象为原型,克隆出新的对象。克隆出的新对象不会影响原型对象。

    要实现克隆要实现Cloneable接口和clone()方法

    注意:clone() 是Object类的本地方法(效率高)

    Cloneable只是一个空接口,但是想要克隆,必须实现Cloneable接口

    public interface Cloneable {
    }

    栗子:

    public class People implements Cloneable {
        private Date birthday;
        private String name;
    
        @Override
        protected People clone() throws CloneNotSupportedException {
            People p = (People) super.clone();
            return p;
        }
    
        public People(Date d, String name){
            birthday = d;
            this.name = name;
        }
        public Date getBirthday() {
            return birthday;
        }
        public void setBirthday(Date birthday) {
            this.birthday = birthday;
        }
    }
    class Test{
        public static void main(String[] args) throws CloneNotSupportedException {
            Date d = new Date(1234567897);
            People p1 = new People(d, "张三");
    
            People p2 = p1.clone();
            System.out.println(p1 == p2); //false 克隆出一个新的对象
            System.out.println(p1.getBirthday());
            System.out.println(p2.getBirthday());  // 两个值完全相同
        }
    }

    这种克隆属于浅克隆:

    仅仅把原型对象的值全部克隆给新对象,包括原型对象的一些引用地址(克隆过后,新/原型对象的引用地址指向同一个地址)

    深克隆:连同属性也一起克隆

    @Override
        protected People clone() throws CloneNotSupportedException {
            People p = (People) super.clone();
            p.birthday = (Date) this.birthday.clone();
            return p;
        }

    利用序列化和反序列化 实现深克隆:

    class Test{
        public static void main(String[] args) throws CloneNotSupportedException, IOException, ClassNotFoundException {
            Date d = new Date(1234567897);
            People p1 = new People(d, "张三");
    
            //序列化
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(p1);
            byte[] bytes = bos.toByteArray();  //这个字节数组里面有对象的状态和对象属性的值
            oos.close();
            bos.close();
            //反序列化
            ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
            ObjectInputStream ois = new ObjectInputStream(bis);
            People p2 = (People) ois.readObject();
    
    
            System.out.println(p1.getBirthday());
            System.out.println(p2.getBirthday());
            //修改原型对象的属性
            p1.setBirthday(new Date(987654321));
            System.out.println(p1.getBirthday());
            System.out.println(p2.getBirthday());
        }
    }

    结果:

  • 相关阅读:
    使用pandas的get_dummies对类目型的特征因子化
    关于RandomForestRegressor,补全null数值
    关于train_test_split和cross_val_score交叉检验
    关于seaborn
    正态分布
    单下划线或双下划线的意义
    MFC中关于运行时类信息及动态创建对象的两个宏的意义(转)
    DPDK
    根据结构体成员地址得到结构体入口地址,内核代码
    多线程频繁写全局变量导致性能降低
  • 原文地址:https://www.cnblogs.com/DDiamondd/p/10969512.html
Copyright © 2020-2023  润新知