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


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

    要实现克隆要实现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());
        }
    }

    结果:

  • 相关阅读:
    PCA算法的最小平方误差解释
    windows下面安装Python和pip终极教程
    理解C/C++的复杂声明
    C++的特殊预处理定义#、##和#@
    虚拟机中linux系统无法打开原保存的显示器配置解决方法
    Visual C++内存泄露检测—VLD工具使用说明
    C++重载、覆盖与隐藏——转载
    python爬虫实战(二)--------千图网高清图
    Linux常用命令12
    Linux常用命令11
  • 原文地址:https://www.cnblogs.com/DDiamondd/p/10969512.html
Copyright © 2020-2023  润新知