• 3.原型模式


    1.如果需要创建大量类似的对象,如果用原型模式就可以节省大量时间。原型模式用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。用这种方式创建对象非常高效,根本无须知道对象创建的细节。

    2.原型模式的实现方式依赖java的 clone()方法,实现 Cloneable 就可以实现对象的克隆。克隆可分为浅克隆和深克隆两种方法,java的clone()是浅克隆。

    (1)浅克隆:浅克隆会创建一个新对象,对原对象进行一个完全复制。如果原对象的属性是基本数据类型则进行值传递,如果是引用类型,则传引用。简而言之就是,浅克隆对于基本数据类型复制一个新的出来,新对象和原对象是两份,如果对于引用类型(对象)的属性,则把原来对象的内存地址赋给新对象,俩个引用类型的属性指向的内存地址相同,如果原对象指向地址值改了,克隆对象也会改变。

    (2)深克隆:区别于浅克隆的是,不光对基本类型进行复制,还对引用类型进行复制。克隆对象和原对象是不同的两份,修改原对象对克隆对象没有影响。

    3.实现浅克隆

    package com.java.dp.copy;
    
    import lombok.Data;
    import lombok.ToString;
    
    /**
     * @Author lizhilong
     * @create 2019/12/2 15:33
     * @desc
     */
    @Data
    @ToString
    public class Student implements Cloneable{
    
        private String name;
    
        private Integer age ;
    
        private Subject subject;
    
        @Override
        public Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    
    }
    package com.java.dp.copy;
    
    import lombok.Data;
    
    /**
     * @Author lizhilong
     * @create 2019/12/2 15:34
     * @desc
     */
    @Data
    public class Subject {
    
        private String name;
    
        private Double score;
    }
    package com.java.dp.copy;
    
    /**
     * @Author lizhilong
     * @create 2019/12/2 15:42
     * @desc
     */
    public class CopyMain {
    
        public static void main(String[] args) throws CloneNotSupportedException {
            Student st1 = new Student();
            st1.setName("小明");
            st1.setAge(19);
            Subject subject = new Subject();
            subject.setName("语文");
            subject.setScore(88.9);
            st1.setSubject(subject);
            System.out.println("st1:"+st1.toString());
    
            Student st2 = (Student) st1.clone();
            System.out.println("st2:"+st2.toString());
    
            subject.setName("数学");
            System.out.println("------------------------------------------------");
            System.out.println("修改后st1:"+st1.toString());
            System.out.println("修改后st2:"+st2.toString());
        }
    }
    st1:Student(name=小明, age=19, subject=Subject(name=语文, score=88.9))
    st2:Student(name=小明, age=19, subject=Subject(name=语文, score=88.9))
    ------------------------------------------------
    修改后st1:Student(name=小明, age=19, subject=Subject(name=数学, score=88.9))
    修改后st2:Student(name=小明, age=19, subject=Subject(name=数学, score=88.9))

    可以发现,当引用对象修改了以后,两个student对象均受到影响,无法做到只修改其中一个的值。

    4.实现深克隆

    package com.java.dp.copy;
    
    import lombok.Data;
    
    /**
     * @Author lizhilong
     * @create 2019/12/2 15:34
     * @desc
     */
    @Data
    public class Subject implements Cloneable{
    
        private String name;
    
        private Double score;
    
        @Override
        public Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    }
    package com.java.dp.copy;
    
    import lombok.Data;
    import lombok.ToString;
    
    /**
     * @Author lizhilong
     * @create 2019/12/2 15:33
     * @desc
     */
    @Data
    @ToString
    public class Student implements Cloneable{
    
        private String name;
    
        private Integer age ;
    
        private Subject subject;
    
        @Override
        public Object clone() throws CloneNotSupportedException {
            Student student = (Student) super.clone();
            student.subject = (Subject)subject.clone();
            return student;
        }
    
    }
    package com.java.dp.copy;
    
    /**
     * @Author lizhilong
     * @create 2019/12/2 15:42
     * @desc
     */
    public class CopyMain {
    
        public static void main(String[] args) throws CloneNotSupportedException {
            Student st1 = new Student();
            st1.setName("小明");
            st1.setAge(19);
            Subject subject = new Subject();
            subject.setName("语文");
            subject.setScore(88.9);
            st1.setSubject(subject);
            System.out.println("st1:"+st1.toString());
    
            Student st2 = (Student) st1.clone();
            System.out.println("st2:"+st2.toString());
    
            subject.setName("数学");
            System.out.println("------------------------------------------------");
            System.out.println("修改后st1:"+st1.toString());
            System.out.println("修改后st2:"+st2.toString());
        }
    }
    st1:Student(name=小明, age=19, subject=Subject(name=语文, score=88.9))
    st2:Student(name=小明, age=19, subject=Subject(name=语文, score=88.9))
    ------------------------------------------------
    修改后st1:Student(name=小明, age=19, subject=Subject(name=数学, score=88.9))
    修改后st2:Student(name=小明, age=19, subject=Subject(name=语文, score=88.9))

    可以看到,修改了subject的name属性后,只有st1 受到影响,st2 没有受到影响,因为它的引用对象属性也是新对象。

  • 相关阅读:
    VSCode
    git CAPTCHA required
    css :active
    节流 防抖
    判断数据类型
    http协议的三次握手和四次挥手
    http协议
    发布网站相关信息
    获取任意两个数之间多个随机数的方法;
    数组中的12个方法;
  • 原文地址:https://www.cnblogs.com/li-zhi-long/p/11971259.html
Copyright © 2020-2023  润新知