当前位置: 首页 > 面试题库 >

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

陆仲渊
2023-03-14
问题内容

我读了《有效Java》,其中指出最好使用来实现单例enum

此方法在功能上等效于公共领域方法,除了它更简洁,免费提供序列化机制,甚至针对复杂的序列化或反射攻击,还提供了针对多重实例化的明确保证。尽管此方法尚未得到广泛采用,但是单元素枚举类型是实现单例的最佳方法。

尽管如此,这似乎是在动态序列化和真正的单实例上实现的折衷方案,但您却失去了经典单例的更友好的OOP方法。枚举不能被继承,只能实现一个接口,如果要提供框架类,则需要创建一个帮助器类。

因此,除了上述原因之外,我们为什么还要接受枚举作为单例的最佳实现?


问题答案:

这似乎是在快速进行序列化时要取得的权衡

对我来说写这样的东西更简单,更简洁

enum Singleton {
    INSTANCE;
}

如果您需要编写更多代码或引入复杂性,则可以这样做,但是IMHO很少需要这样做。

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

我发现使用字段更简单。

枚举不能被继承,

没错,但是有多个单例本身就值得怀疑。枚举可以从接口继承,这使您可以将一种实现交换为另一种实现。

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

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

顺便说一句:您可以使用enum帮助程序类

enum Helper {;
    public static my_static_methods_here;
}

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

我会遵循YAGNI原则。仅开发所需的内容,而不开发您可能需要的内容。



 类似资料:
  • 问题内容: 在SO问题上编写的内容基础上构建Java最佳单例实现 -即关于使用枚举创建单例-之间的区别/优点/缺点(省略构造函数) and then calling 和 and then calling 问题答案: 假设您要绑定到将使用给定对象的属性的对象-您可以非常轻松地传递Elvis.INSTANCE,但是您不能传递Elvis.class并期望它找到该属性(除非经过故意编码才能找到类的静态属性

  • 问题内容: Java不允许枚举位于接口内部,但是默认情况下,接口内部的每个数据成员都是。有人可以澄清吗? 问题答案: 枚举不能是最终的,因为编译器将为程序员明确为其定义实现的每个枚举条目生成子类。 此外,根据JLS第8.9节,没有实例具有自己的类主体的枚举是隐式最终的。

  • 问题内容: 假设我有一个枚举: 正如所示这个答案由lucasmo,枚举值存储在它们初始化的顺序静态数组,你可以在以后检索(的克隆)这个数组。 现在假设我要实现,使得以下所有表达式求和: 我当前的实现如下: 和类似的方法。 但是,此代码充其量似乎很麻烦(例如,“空” 循环,可能会滥用计数器变量,最坏的情况下可能是错误的(可能是反射)。 Java 7中枚举类型的最佳实现方法和方法是什么? 注意: 我不

  • 具有以下定义 是否有一种方法可以正确执行比较以使用标准等式:

  • 问题内容: 我刚刚发现Java允许枚举实现接口。有什么好的用例? 问题答案: 枚举不仅仅代表被动集(例如颜色)。他们可以代表与功能更复杂的对象,所以你可能想进一步功能添加到这些是那么-例如,你可能如接口,等等。支持这些和组件。

  • 问题内容: 我们有一个REST API,客户端可以在其中提供代表Java Enums中服务器上定义的值的参数。 因此,我们可以提供一个描述性错误,我们将此方法添加到每个Enum中。似乎我们只是在复制代码(错误)。有更好的做法吗? 更新 :提供的默认错误消息为。我想提供一个来自API的更具描述性的错误。 问题答案: 可能可以实现通用静态方法。 像这样 那么你就可以 或显式调用实用程序类查找方法。