美文网首页
枚举单例模式

枚举单例模式

作者: 睦月MTK | 来源:发表于2020-01-26 14:24 被阅读0次

    statement:本篇内容只是建立在我目前经验的基础之上,必然有不完善甚至是不正确的地方,请谨慎阅读,如果能指出错误与不足之处,更是不甚感激


    一、传统单例模式的缺点
    • 传统单例模式的常规写法
    public class SingletonTest {
        private static final SingletonTest instance= new SingletonTest ();
        private SingletonTest () {}
        public static SingletonTest getInstance() {
            return instance;
        }
    }
    
    • 传统单例模式存在的隐患
      由于序列化会生成新的对象,所以如果使用了传统单例模式实现的类要实现序列化,则必须多操作一番:
      • 添加readResolve方法,该方法会在序列化之后被调用,其返回的对象将代替readObject生成的新对象
      • 保证所有非基础类型的实例域都是transient修饰的,transient修饰的域不参与序列化,也保证了不会有非法操作(非法操作者可以把非transient非基础类型的实例域替换为自己的对象,该对象包含一个readResolve方法,该对象会被先序列化,接着执行该对象的readResolve方法返回一个恶意的值,这样原来的值就完全被修改了)执行在readResolve方法之前
      • 除此之外,利用反射也可以生成新的实例,所以得修改构造器,使其在尝试创建新的实例时抛出异常
    public class SingletonTest implements Serializable{
        private static final long serialVersionUID = 113454417668258756L;
        private static final SingletonTest instance= new SingletonTest ();
        //基础类型实例域
        private int fieldInt;
        //非基础类型实例域
        private transient String fieldString;
        private SingletonTest () {
            if(Objects.nonNull(instance)) throw new IllegalStateException("try to create new instance");
        }
        public static SingletonTest getInstance() {
            return instance;
        }
        
        private Object readResolve() {
            return instance;
        }
    }
    

    二、枚举单例模式的写法与优点
    • 枚举单例模式的写法
    public enum EnumSingleton {
        INSTANCE;
    }
    
    • 枚举单例模式的优点
      • 枚举本身的机制保证其不会受到反射攻击
      • 枚举本身就是可序列化的,且不会因为序列化而生出新的对象
      • 枚举写法简单
    • 什么?你说写法过于简单,看不懂怎么用?回去好好看看枚举怎么用!
    public enum EnumSingleton {
        INSTANCE("hello");
        private String name;
        
        private EnumSingleton(String name) {
            this.name = name;
        }
        
        public String getName(){
            return name;
        }
        
        public static void main(String[] args) {
            EnumSingleton es = EnumSingleton.INSTANCE;
            System.out.println(es.getName());
        }
    }
    

    参考文档:
    [1] 《Effective Java》

    相关文章

      网友评论

          本文标题:枚举单例模式

          本文链接:https://www.haomeiwen.com/subject/datdthtx.html