• 设计模式——原型模式05


    原型模式核心复制,每次new出来的对象完全不一样,实现对象之间的隔离。 学习前最好先掌握jAVA值传递和深浅拷贝
    设计模式,一定要敲代码理解

    浅拷贝

    克隆出对象,其中两者的引用类型属性是同一个对象。

    对象信息

    /**
     * @author ggbond
     * @date 2024年04月03日 08:38
     */
    public class Mankind01 implements Cloneable {
        private  int age;
        private Date birth;
    
        public Mankind01(int age, Date birth){
            this.age=age;
            this.birth=birth;
        }
    
        public int getAge() {
            return age;
        }
    
        public Date getBirth() {
            return birth;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public void setBirth(Date birth) {
            this.birth = birth;
        }
    
        @Override
        protected Mankind01 clone() throws CloneNotSupportedException {
    
            return (Mankind01) super.clone();
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    测试

    /**
     * @author ggbond
     * @date 2024年04月03日 08:42
     *
     */
    public class test01 {
        public static void main(String[] args) throws Exception {
            Date birth=new Date(2022,4,3);
            int age=25;
            Mankind01 m1=new Mankind01(age,birth);
            Mankind01 m2=m1.clone();
            System.out.println("m1.age:"+m1.getAge()+"  "+"m2.age:"+m2.getAge());
            System.out.println("m1.birth:"+m1.getBirth()+"  "+"m2.birth:"+m2.getBirth());
            System.out.println("-----------");
    
            age=21; birth.setTime(1232321321L);
    
            System.out.println(m1.getBirth() == m2.getBirth()); // true
            System.out.println("m1.age:"+m1.getAge()+"  "+"m2.age:"+m2.getAge());
            System.out.println("m1.birth:"+m1.getBirth()+"  "+"m2.birth:"+m2.getBirth());
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    测试结果发现, m1,m2 中的属性 引用类型 Date birth 是指向同一个对象

    m1.age:25  m2.age:25
    m1.birth:Wed May 03 00:00:00 CST 3922  m2.birth:Wed May 03 00:00:00 CST 3922
    -----------
    true
    m1.age:25  m2.age:25
    m1.birth:Thu Jan 15 14:18:41 CST 1970  m2.birth:Thu Jan 15 14:18:41 CST 1970
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

    深拷贝

    对象信息

    /**
     * @author ggbond
     * @date 2024年04月03日 08:38
     */
    public class Mankind02 implements Cloneable {
        private  int age;
        private Date birth;
    
        public Mankind02(int age, Date birth){
            this.age=age;
            this.birth=birth;
        }
    
        public int getAge() {
            return age;
        }
    
        public Date getBirth() {
            return birth;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public void setBirth(Date birth) {
            this.birth = birth;
        }
    
        @Override
        protected Mankind02 clone() throws CloneNotSupportedException {
            Mankind02 m = (Mankind02) super.clone();
            m.setBirth((Date) birth.clone());
            return m;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    测试

    /**
     * @author ggbond
     * @date 2024年04月03日 08:42
     * 原型模式,本质是克隆复制对象。
     */
    public class test02 {
        public static void main(String[] args) throws Exception {
            Date birth=new Date(2022,4,3);
            int age=25;
            Mankind02 m1=new Mankind02(age,birth);
            Mankind02 m2=m1.clone();
            System.out.println("m1.age:"+m1.getAge()+"  "+"m2.age:"+m2.getAge());
            System.out.println("m1.birth:"+m1.getBirth()+"  "+"m2.birth:"+m2.getBirth());
            System.out.println("-----------");
    
            age=21; birth.setTime(123232321L);
    
            System.out.println(m1.getBirth() == m2.getBirth()); // true
            System.out.println("m1.age:"+m1.getAge()+"  "+"m2.age:"+m2.getAge());
            System.out.println("m1.birth:"+m1.getBirth()+"  "+"m2.birth:"+m2.getBirth());
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    结果

    m1.age:25  m2.age:25
    m1.birth:Wed May 03 00:00:00 CST 3922  m2.birth:Wed May 03 00:00:00 CST 3922
    -----------
    false
    m1.age:25  m2.age:25
    m1.birth:Fri Jan 02 18:13:52 CST 1970  m2.birth:Wed May 03 00:00:00 CST 3922
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

    总结

    使用场景:需要到大量相同对象,但内部内容或结构可能进行修改。思考上述被复制对象中如果含多层引用,克隆包含循环引用的复杂对象可能会非常麻烦。

    代码下载

    代码下载

  • 相关阅读:
    000 我和网安的故事.doc
    P7071 [CSP-J2020] 优秀的拆分
    QreryRunner类和ResultSetHandler
    startActivityForResult废弃了,用Activity Result API吧
    maven构建jar包运行后出现中文乱码问题解决
    Python 基础30道测试题
    ESP8266 WiFi物联网智能插座—项目简介
    2022-08-04
    练习题60:接口练习2:真的鸭子会游泳 木头鸭子不会游泳 橡皮鸭子会游泳
    一段惊呆下巴的 JavaScript 代码
  • 原文地址:https://blog.csdn.net/qq_45178641/article/details/137332052