Josh Bloch 建议使用单元素类型来实现单例(请参阅有效的 Java 第 2 版,第 3 项:使用私有构造函数或枚举类型强制实施单例属性)。enum
有些人认为这是一个黑客,因为它没有清楚地传达意图,但它确实有效。
以下示例直接取自本书。
public enum Elvis {
INSTANCE;
public void leaveTheBuilding() { ... }
}
以下是他的结束语:
这种方法[...]更简洁,免费提供序列化机制,并提供针对多个实例化的铁定保证,即使面对复杂的序列化或反射攻击也是如此。虽然这种方法尚未被广泛采用,但单元素枚举类型是实现单例的最佳方式。
关于恒定单例保证enum
枚举类型除了由其枚举常量定义的实例外,没有其他实例。尝试显式实例化枚举类型 (§15.9.1) 是编译时错误。
中的方法确保永远不会克隆枚举常量,序列化机制的特殊处理可确保永远不会由于反序列化而创建重复的实例。禁止枚举类型的反射实例化。总之,这四件事可确保除了枚举常量定义的实例之外,不存在枚举类型的实例。final clone
Enum
关于延迟初始化
以下代码段:
public class LazyElvis {
enum Elvis {
THE_ONE;
Elvis() {
System.out.println("I'M STILL ALIVE!!!");
}
}
public static void main(String[] args) {
System.out.println("La-dee-daaa...");
System.out.println(Elvis.THE_ONE);
}
}
生成以下输出:
La-dee-daaa...
I'M STILL ALIVE!!!
THE_ONE
如您所见,常量在首次访问之前不会通过构造函数实例化。THE_ONE