Java 利用枚举实现单例模式

引言

单例模式比较常见的实现方法有懒汉模式,DCL模式公有静态成员等,从Java 1.5版本起,单元素枚举实现单例模式成为最佳的方法。java


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;
    ...
}

对于上面的例子,咱们能够把Type看做一个类,而把A,B,C,D看做类的Type的实例。 
固然,这个构建实例的过程不是咱们作的,一个enum的构造方法限制是private的,也就是不容许咱们调用。ide

“类”方法和“实例”方法

上面说到,咱们能够把Type看做一个类,而把A,B。。。看做Type的一个实例。一样,在enum中,咱们能够定义类和实例的变量以及方法。看下面的代码:spa

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()来调用就能够了。 最后,对于某个实例而言,还能够实现本身的实例方法。再看下下面的代码: 线程

enum Type{
A{
    public String getType() {
        return "I will not tell you";
    }
},B,C,D;
static int value;

public static int getValue() {
    return value;
}

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

 这里,A实例后面的{…}就是属于A的实例方法,能够经过覆盖本来的方法,实现属于本身的定制。 blog

除此以外,咱们还能够添加抽象方法在enum中,强制ABCD都实现各自的处理逻辑:继承

enum Type{
    A{
        public String getType() {
            return "A";
        }
    },B {
        @Override
        public String getType() {
            return "B";
        }
    },C {
        @Override
        public String getType() {
            return "C";
        }
    },D {
        @Override
        public String getType() {
            return "D";
        }
    };

    public abstract String getType();
}

枚举单例

有了上面的基础,咱们能够来看一下枚举单例的实现方法:资源

class Resource{
}

public enum SomeThing {
    INSTANCE;
    private Resource instance;
    SomeThing() {
        instance = new Resource();
    }
    public Resource getInstance() {
        return instance;
    }
}

  

 上面的类Resource是咱们要应用单例模式的资源,具体能够表现为网络链接,数据库链接,线程池等等。 get

获取资源的方式很简单,只要 SomeThing.INSTANCE.getInstance() 便可得到所要实例。下面咱们来看看单例是如何被保证的: 
首先,在枚举中咱们明确了构造方法限制为私有,在咱们访问枚举实例时会执行构造方法,同时每一个枚举实例都是static final类型的,也就代表只能被实例化一次。在调用构造方法时,咱们的单例被实例化。 
也就是说,由于enum中的实例被保证只会被实例化一次,因此咱们的INSTANCE也被保证明例化一次。 
能够看到,枚举实现单例仍是比较简单的,除此以外咱们再来看一下Enum这个类的声明:

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

能够看到,枚举也提供了序列化机制。某些状况,好比咱们要经过网络传输一个数据库链接的句柄,会提供不少帮助。 
最后借用 《Effective Java》一书中的话,

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

相关文章
相关标签/搜索