Java基础

创建一个单例

Effective Java作者Josh Bloch 提倡使用枚举的方式。

枚举写法简单

public enum EasySingleton{
 INSTANCE;
}
你可以通过EasySingleton.INSTANCE来访问。

枚举自己处理序列化

我们知道,以前的所有的单例模式都有一个比较大的问题,就是一旦实现了Serializable接口之后,就不再是单例的了,因为,每次调用 readObject()方法返回的都是一个新创建出来的对象,有一种解决办法就是使用readResolve()方法来避免此事发生。但是, 为了保证枚举类型像Java规范中所说的那样,每一个枚举类型极其定义的枚举变量在JVM中都是唯一的,在枚举类型的序列化和反序列化上,Java做了特殊的规定。

在序列化的时候Java仅仅是将枚举对象的name属性输出到结果中,反序列化的时候则是通过java.lang.Enum的valueOf方法来根据名字查找枚举对象。同时,编译器是不允许任何对这种序列化机制的定制的,因此禁用了writeObject、readObject、readObjectNoData、writeReplace和readResolve等方法。

所以,JVM对序列化有保证。


枚举实例创建是thread-safe(线程安全的)

根据Java的ClassLoader机制,当一个Java类第一次被真正使用到的时候静态资源被初始化、Java类的加载和初始化过程都是线程安全的。所以,创建一个enum实例是线程安全的。

例如:

enum Type{
    A,B,C,D;
}

创建上面的enum时,编译器会自动为我们生成一个继承自java.lang.Enum的类。

class Type extends Enum{
    public static final Type A;
    public static final Type B;
    ...
}

可以看到每个枚举实例都是static final类型的,也就表明只能被实例化一次。所以enum中的实例被保证只会被实例化一次,在我们访问枚举实例时会执行构造方法和初始化变量。

懒加载模式

public class SingletonDeSign {
    public static void main(String[] args){
        System.out.println("枚举类实现单例懒加载");

        ConnectPool connectPool = ConnectPool.INSTANCE;
        ConnectPool connectPool1 = ConnectPool.INSTANCE;
        String connect = connectPool1.getConnect();
    }
}

enum ConnectPool{
    INSTANCE;
    ConnectPool(){
        System.out.println("执行ConnectPool的构造函数");
    }

    public String getConnect(){
        return "connect";
    }
}

类加载机制


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值