zoukankan      html  css  js  c++  java
  • 设计模式课程 设计模式精讲 9-3 原型模式-克隆破坏单例

    1    代码演练

    1.1  克隆破坏单例

    1.2  如何防范克隆破坏单例

    1.3  小问

    1    代码演练
    1.1  克隆破坏单例

    实体类:

    package com.geely.design.pattern.creational.singleton;
    
    import java.io.Serializable;
    
    public class HangrySingleton implements Serializable,Cloneable {
    
    
        /**
         * 声明私有常量,当类初始化的时候就已经赋值了。饿汉式在类初始化的时候只加载一次。
         * 所以也不会存在多线程的问题。
         */
        private final static HangrySingleton hangrySingleton;
    
        static {
            hangrySingleton= new HangrySingleton();
        }
    
        /**
         * 声明私有构造方法
         * 因为饿汉式和静态类在类初始化的时候,已经附上了对象,反射取值的时候该对象一定有值。
         */
        private HangrySingleton(){
            if(hangrySingleton != null){
                throw new RuntimeException("单例构造器禁止反射!");
            }
        }
    
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    
        /**
         * 防止序列化和反序列化对单例模式进行破坏
         */
        private Object readResolve(){
            return hangrySingleton;
        }
    
        /**
         * 提供对外接口,获得对象
         * @return
         */
        public static HangrySingleton getInstance(){
            return hangrySingleton;
        }
    }

    测试类:

    package com.geely.design.pattern.creational.prototype;
    
    import com.geely.design.pattern.creational.singleton.HangrySingleton;
    import sun.reflect.Reflection;
    
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.util.Date;
    
    public class Test2 {
        public static void main(String [] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
               /* Date date1 = new Date();
                Pig pig1 = new Pig("peiqi",date1);
                Pig pig2 = (Pig) pig1.clone();
                System.out.println(pig1);
                System.out.println(pig2);
    
    
                //预期修改pig1的生日,没想到pig2的生日也改了
                pig1.getBirthday().setTime(0L);
                System.out.println(pig1);
                System.out.println(pig2);*/
    
    
               //如何破坏单例模式?克隆方式破坏单例模式
                HangrySingleton hangrySingleton = HangrySingleton.getInstance();//取得单例对象
                //反射打开方法的权限
                Method method = hangrySingleton.getClass().getDeclaredMethod("clone");
                method.setAccessible(true);
                //克隆方法是protected权限,只有本类或者派生的类中使用,所以需要打开权限
                HangrySingleton hangrySingleton2 = (HangrySingleton) method.invoke(hangrySingleton);
                System.out.println(hangrySingleton);
                System.out.println(hangrySingleton2);
    
        }
    }

    打印日志:

    "C:Program FilesJavajdk1.7.0_79injava.exe" "-javaagent:D:javadevolopKitideaanZhIntelliJ IDEA Community Edition 2018.1.4libidea_rt.jar=12734:D:javadevolopKitideaanZhIntelliJ IDEA Community Edition 2018.1.4in" -Dfile.encoding=UTF-8 -classpath "C:Program FilesJavajdk1.7.0_79jrelibcharsets.jar;C:Program FilesJavajdk1.7.0_79jrelibdeploy.jar;C:Program FilesJavajdk1.7.0_79jrelibextaccess-bridge-64.jar;C:Program FilesJavajdk1.7.0_79jrelibextdnsns.jar;C:Program FilesJavajdk1.7.0_79jrelibextjaccess.jar;C:Program FilesJavajdk1.7.0_79jrelibextlocaledata.jar;C:Program FilesJavajdk1.7.0_79jrelibextsunec.jar;C:Program FilesJavajdk1.7.0_79jrelibextsunjce_provider.jar;C:Program FilesJavajdk1.7.0_79jrelibextsunmscapi.jar;C:Program FilesJavajdk1.7.0_79jrelibextzipfs.jar;C:Program FilesJavajdk1.7.0_79jrelibjavaws.jar;C:Program FilesJavajdk1.7.0_79jrelibjce.jar;C:Program FilesJavajdk1.7.0_79jrelibjfr.jar;C:Program FilesJavajdk1.7.0_79jrelibjfxrt.jar;C:Program FilesJavajdk1.7.0_79jrelibjsse.jar;C:Program FilesJavajdk1.7.0_79jrelibmanagement-agent.jar;C:Program FilesJavajdk1.7.0_79jrelibplugin.jar;C:Program FilesJavajdk1.7.0_79jrelib
    esources.jar;C:Program FilesJavajdk1.7.0_79jrelib
    t.jar;F:xiangmu3XinIdeadesign_pattern	argetclasses" com.geely.design.pattern.creational.prototype.Test2
    com.geely.design.pattern.creational.singleton.HangrySingleton@63ce0e18
    com.geely.design.pattern.creational.singleton.HangrySingleton@6cff7cd8
    
    Process finished with exit code 0
    1.2  如何防范克隆破坏单例

    a  单例类不实现克隆接口

    b  这样修改

    package com.geely.design.pattern.creational.singleton;
    
    import java.io.Serializable;
    
    public class HangrySingleton implements Serializable,Cloneable {
    
    
        /**
         * 声明私有常量,当类初始化的时候就已经赋值了。饿汉式在类初始化的时候只加载一次。
         * 所以也不会存在多线程的问题。
         */
        private final static HangrySingleton hangrySingleton;
    
        static {
            hangrySingleton= new HangrySingleton();
        }
    
        /**
         * 声明私有构造方法
         * 因为饿汉式和静态类在类初始化的时候,已经附上了对象,反射取值的时候该对象一定有值。
         */
        private HangrySingleton(){
            if(hangrySingleton != null){
                throw new RuntimeException("单例构造器禁止反射!");
            }
        }
    
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return getInstance();
        }
    
        /**
         * 防止序列化和反序列化对单例模式进行破坏
         */
        private Object readResolve(){
            return hangrySingleton;
        }
    
        /**
         * 提供对外接口,获得对象
         * @return
         */
        public static HangrySingleton getInstance(){
            return hangrySingleton;
        }
    }
     1.3  小问

    有哪些方式能够破坏单例模式呢?

    克隆,

    自己推测:序列化,反射攻击(可以翻看前边视频,后边有时间了再来巩固)

      

     

  • 相关阅读:
    mysql单个表内去重多个重复的字段
    scrapy xpath有空格处理
    有道选择语言性翻译
    豆瓣源
    scrapy 编码
    西祠代理获取
    有道翻译
    远程连接服务器for Linux
    ECshop通过文章分类的ID实现不同模板
    创建WordPress管理员账号
  • 原文地址:https://www.cnblogs.com/1446358788-qq/p/11470779.html
Copyright © 2011-2022 走看看