设计模式【1.2】-- 枚举式单例有那么好用么?

1. 单例是什么?

单例模式:是一种创建型设计模式,目的是保证全局一个类只有一个实例对象,分为懒汉式和饿汉式。所谓懒汉式,类似于懒加载,需要的时候才会触发初始化实例对象。而饿汉式正好相反,项目启动,类加载的时候,就会创建初始化单例对象。

前面说过单例模式以及如何破坏单例模式,我们一般情况尽可能阻止单例模式被破坏,于是各种序列化,反射,以及克隆的手段,我们都需要考虑进来,最终的代码如下:


import java.io.Serializable;

public class Singleton implements Serializable {
   
    private static int num = 0;

  	// valitile禁止指令重排
    private volatile static Singleton singleton;

  	// 禁止多次反射调用构造器
    private Singleton() {
   
        synchronized (Singleton.class) {
   
            if (num == 0) {
   
                num++;
            } else {
   
                throw new RuntimeException("Don't use this method");
            }
        }
    }

    public static Singleton getSingleton() {
   
        if (singleton == null) {
   
            synchronized (Singleton.class) {
   
                if (singleton == null) {
   
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
  	// 禁止序列化的时候,重新生成对象
    private Object readResolve() {
   
        return singleton;
    }
}

前面提过破坏序列化的四种方式:

  • 没有将构造器私有化,可以直接调用。
  • 反射调用构造器
  • 实现了cloneable接口
  • 序列化与反序列化

2. 枚举的单例可以被破坏么?

但是突然想到一个问题,一般都说枚举的方式实现单例比较好,较为推荐。真的是这样么?这样真的是安全的么?

那我们就试试,看看各种手段,能不能破坏它的单例。首先我们来写一个单例枚举类:

public enum SingletonEnum {
   
    INSTANCE;
    public SingletonEnum getInstance(){
   
        return INSTANCE;
    }
}

在命令行执行以下的命令看上面的枚举类编译之后到底是什么东西?

javac SingletonEnum.java
javap SingletonEnum

public final class singleton.SingletonEnum extends java.lang.Enum<singleton.SingletonEnum> {
   
  public static final singleton.SingletonEnum INSTANCE;
  public static singleton.SingletonEnum[] values();
  public static singleton.SingletonEnum valueOf(java.lang.String);
  public singleton.SingletonEnum getInstance();
  static 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值