相信接触过设计模式的同学都知道,单例的一种经典实现方式就是private的构造函数,但直到我看到这一章节内容的时候,才突然顿悟原来枚举类型也是可以强化单例属性的,自愧个人的融会贯通能力还有待加强。
实现单例方式一:
// Singleton with public final field public class Elvis { public static final Elvis INSTANCE= new Elvis(); private Elvis() { .. . } }
这种实现方式有一个缺点就是可以借助反射机制里的AccessibleObject.setAccessible来强制修改构造函数成为public的
实现单例方式二:
// Singleton with static factory public class Elvis { private static final Elvis INSTANζE = new Elvis(); private Elvis() { ... } public static Elvis getInstance() {return INSTANCE; } }
在实际抉择中,如果用到了以下某种优势,则优先考虑第二种实现,否则考虑第一种单例实现:
可以很容易被修改成非单例的(修改getInstance的返回语句即可)
可以使用Elvis::instance语法
此外,为了防止每次序列化和反序列化都创建一个新实例而破坏了单例特性,需要在Elvis类中添加一个方法:
private Object readResolve () { return INSTANCE; }
实现单例方式三:
这种方式也是我原先没有想到的,声明包含单个元素的枚举类型来实现:
public enum Elvis { INSTANCE; public void leaveTheBuilding() { .. . } }
其中Elvis.INSTANCE可以获得单例,Elvis.INSTANCE.leaveTheBuilding();调方法。
这种方式也是作者极力推荐的一种方式,无偿地提供了序列化机制,绝对防止多次实例化。单元素的枚举类型经常成为实现Singleton的最佳方法。