为什么枚举是单例的最佳实现



我阅读了Effective Java,其中指出单例最好使用enum实现。

这种方法在功能上等同于公共字段方法,只是它更简洁,免费提供序列化机制,并为防止多次实例化提供了铁一般的保证,即使面对复杂的序列化或反射攻击也是如此。虽然这种方法尚未被广泛采用,但单元素枚举类型是实现单例的最佳方式。

尽管如此,这似乎是实现动态序列化和真正的单个实例的一种权衡,但您会失去经典单例的更友好的OOP方法。枚举不能被继承,只能实现一个接口,如果你想提供一个骨架类,你需要创建一个辅助类。

那么,除了上述原因之外,我们为什么要接受enum作为单例的最佳实现呢?

这似乎是实现动态序列化的一种权衡

对我来说,写这样的东西要简单简洁得多

enum Singleton {
    INSTANCE;
}

如果您需要编写更多的代码或引入复杂性,那么就这样做,但IMHO很少需要这样做。

您失去了经典单例的更友好的OOP方法。

我发现使用字段更简单。

枚举无法继承,

没错,但拥有多个单身汉本身就令人怀疑。枚举可以从允许您将一个实现交换为另一个实现的接口继承。

如果你想提供一个骨架类,你需要创建一个辅助类

助手类没有任何状态。骨架类可能具有某种状态,在这种情况下需要委派。

BTW:您可以将enum用于辅助类

enum Helper {;
    public static my_static_methods_here;
}

为什么我们应该接受enum作为单例的最佳实现

我会遵循YAGNI原则。只发展你需要的东西,而不是你想象中你可能需要的东西。

枚举不能继承

这是枚举中最棒的部分之一,是单核。

如果您可以从singleton继承,那么它就不再是singleton了

不久前在stackoverflow上也有类似的讨论:在Java中实现单例模式的有效方法是什么?

公认的答案提供了关于该主题的良好链接:

Joshua Bloch在他的高效Java中解释了这种方法谷歌I/O 2008上的重加载对话:视频链接。另请参阅他的演示幻灯片30-32(effective_java_reloaded.pdf):

主要的一点是,很难写出一个真正的单例。枚举值保证只存在一次,如Java语言规范§8.9:中所定义

枚举类型除了由其枚举常量定义的实例外,没有其他实例。

最新更新