• 用私有构造器或者枚举类型强化SingleTon(单例)属性


    单例(singleton)就是一个只实例化一次的类。使类成为单例可能会使它的测试变得困难,因为除非它实现了作为其类型的接口,否则不可能用模拟实现来代替这个单例。下面是几种实现单例的方法:

    1、共有静态成员是final类型

    // Singleton with public final field
    public class Elvis {
        public static final Elvis INSTANCE = new Elvis();
        private Elvis() { ... }
    }
    

    私有构造器之后执行一次,实例化Elvis.INSTANCE属性,由于缺少公有(public)的或者受保护(protected)的构造器,所以Elvis一旦被实例化,就只会存在一个Elvis的实例(注:反射是可以实现多次调用私有的构造器,若需要抵御这种攻击,则可以修改私有构造器,让它在被创建第二个实例时,抛出异常,或直接返回第一个实例对象)。

    2、公有的成员是一个静态方法。

    // Singleton with static factory
    public class Elvis {
        private static final Elvis INSTANCE = new Elvis();
        private Elvis() { ... }
        public static Elvis getInstance() { return INSTANCE; }
    }
    

     这个方式可以通过公有静态方法将类改为非单例,但用户代码不需要改变。

    为了使利用这其中一种方法实现的SingleTon类变成是可序列化的(Serializable),仅仅在申明上加上“implements Serializable”是不够的。为了维护并保证SingleTon,必须申明所有实例都是瞬时的(transient),并提供一个readResolve方法,否者,每次反序列化一个序列化的实例时,都会创建一个新的实例,比如说,在我们的实例中,会导致“假冒的Elvis”。为了防止这种情况,要在Elvis类中加入下面这个readResolve方法:

    参考地址:https://blog.csdn.net/zhushuai1221/article/details/51780895

    //1、防止反序列化获取多个对象的漏洞。  
    //2、无论是实现Serializable接口,或是Externalizable接口,当从I/O流中读取对象时,readResolve()方法都会被调用到。
    //3、实际上就是用readResolve()中返回的对象直接替换在反序列化过程中创建的对象。
    private Object readResolve(){
          return INSTANCE;   
    }

     3、使用枚举实现单例(最佳方式)

    /**
     * 使用枚举的单例模式
     *
     */
    public class Elvis{
        private Elvis(){} 
    public static Elvis getInstance(){ return Singleton.INSTANCE.getInstance(); } private enum Singleton{ INSTANCE; private Elvis singleton; //JVM会保证此方法绝对只调用一次 Singleton(){ singleton = new Elvis(); } public Elvis getInstance(){ return singleton; } } }

    这种方法是在需要的类中编写一个包含单个元素的枚举类型。无偿的提供了序列化机制,绝对防止多次序列化,即使是在面对复杂的序列化或者反射攻击的时候。

      

  • 相关阅读:
    JavaWeb
    JavaWeb
    appium+python实现手机计算器随机计算
    使用uiautomatorviewer工具遇到以下问题-Unexpected error while obtaining UI hierarchy
    appium+python启动手机淘宝
    appium基本环境搭建
    python多个字典“合并”成一个字典
    HTML基础1-图像
    HTML基础1-文本
    RobotFrame简要安装
  • 原文地址:https://www.cnblogs.com/cq-yangzhou/p/10072367.html
Copyright © 2020-2023  润新知