Java单元素枚举实现单例模式

引言

单例模式比较常见的实现方法有懒汉模式、饿汉模式、DCL(双重检验锁)模式和公有静态成员等,不过自从Java 1.5版本起,单元素枚举实现单例模式成为最佳的方法。


Java中的枚举

枚举的用法比较多,本文主要介绍利用枚举实现单例模式的原理,所以这里顺带介绍一些相关的基础内容。

基本用法

枚举和类类似,一个枚举也可以拥有成员变量、成员方法和构造方法。
先来看枚举最基本的用法:

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

创建enum时,编译器会自动为我们生成一个继承自java.lang.Enum的类,故我们上面的enum可以简单看作:

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

在上面的例子中,我们可以把Type看作一个类,而把A,B,C,D看作类的Type的实例。

当然,这个构建实例的过程不是我们做的,一个enum的构造方法限制是private的,也就是不允许我们调用。

上面有提到,在enum中,我们可以定义成员变量以及成员方法。看下面的代码:

enum Type{
    A,B,C,D;

    static int value;
    public static int getValue() {
        return value;
    }

    String type;
    public String getType() {
        return type;
    }
}

此处在原有的基础上,添加了类方法和实例方法。

我们把Type看做一个类,那么enum中静态的域和方法,都可以视作类方法。和我们调用普通的静态方法一样,这里调用类方法也是通过 Type.getValue()即可调用,访问类属性也是通过Type.value即可访问。

下面的是实例方法,也就是每个实例才能调用的方法。那么实例是什么呢?没错,就是A,B,C,D。所以我们调用实例方法,也就通过 Type.A.getType()来调用就可以了。

其实,对于某个实例而言,还可以实现自己的实例方法;以及可以在枚举中定义抽象方法,再到实例中进行相应的实现。此处就不做过多概述了。

单元素枚举实现

有了上面的基础,我们可以来看一下枚举单例的实现方法:

public enum SomeThing {
    INSTANCE;
   
   public String getSomething(){
     return "SomeThing";
   }  
}

上面的类SomeThing是我们要应用单例模式的资源,具体可以表现为网络连接,数据库连接,线程池等等。

获取资源的方式很简单,只要SomeThing.INSTANCE.getInstance() 即可获得所要实例。下面我们来看看单例是如何被保证的:

首先,在枚举中我们明确了构造方法限制为私有,在我们访问枚举实例时会执行构造方法,同时每个枚举实例都是static final类型的,也就表明只能被实例化一次。在调用构造方法时,我们的单例被实例化。

也就是说,因为enum中的实例被保证只会被实例化一次,所以我们的INSTANCE也被保证实例化一次。


可以看到,枚举实现单例还是比较简单的,除此之外我们再来看一下Enum这个类的声明:

public abstract class Enum<E extends Enum<E>>
        implements Comparable<E>, Serializable

可以看到,枚举也提供了序列化机制。某些情况,比如我们要通过网络传输一个数据库连接的句柄,会提供很多帮助。

最后借用 《Effective Java》一书中的话,

单元素的枚举类型已经成为实现Singleton的最佳方法。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值