对枚举单例有惩罚吗?

发布于 2024-07-27 20:07:51 字数 223 浏览 2 评论 0原文

是否存在与枚举单例模式以任何方式相关的(性能)惩罚*,就像它看起来的那样少于经典的单例模式或内部持有者类习惯用法吗?

* 惩罚,例如在不需要时的可序列化成本等,或者使用率较低,因为很少有开发人员阅读Effective Java 第二版?

Are there (performance) penalties* associated with the Enum Singleton Pattern in any way, as it seems to be used less than the classical singleton pattern or the inner holder class idiom?

* Penalties, such as the cost of serializability in cases when it is not needed and such, or is the usage low because few of the developers read Effective Java 2nd edition?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

柠檬心 2024-08-03 20:07:51

所有 Java 单例模式(无论是这个还是带有私有构造函数和静态访问器的标准)都有这个不好的属性,如果您测试它们(或测试任何远程依赖于它们的东西)可以使用这个并且只能使用这个对象。

例如,如果您想测试依赖于 PrintingSingletonPrintingService 类,您将无法用模拟替换此打印单例,因为它是静态绑定的。

即想象一下

boolean printDocument(Document d) {
  if (PrintingSingleton.INSTANCE.isPrinterEnabled()) {
    PrintingSingleton.INSTANCE.print(d);
  }
  throw new RuntimeExeption("Printing not enabled");
}

通过测试

@Test(expectedExceptions = {RuntimeException.class})
public void testPrinting() {
  PrintingService service = ...
  service.print(new Document());  // How will you simulate 
                                  // throwing an exception?
} 

来测试这个函数。就我个人而言,我会避免以这种方式使用单例,而是通过 Guice、Spring 或 Pico 容器引入依赖注入。 这样,您可以确保仅存在一个对象,同时不会限制自己无法模拟该对象(例如用于测试)。

All Java singleton patterns (both this and the standard with private constructor and static accessor) have this bad property that if you to test them (or test anything that even remotely depends on them) can use this and only this object.

For example if you want to test PrintingService class that depends on PrintingSingleton you will not be able to replace this printing singleton with a mock because it is bound statically.

i.e. imagine testing this function

boolean printDocument(Document d) {
  if (PrintingSingleton.INSTANCE.isPrinterEnabled()) {
    PrintingSingleton.INSTANCE.print(d);
  }
  throw new RuntimeExeption("Printing not enabled");
}

with a test

@Test(expectedExceptions = {RuntimeException.class})
public void testPrinting() {
  PrintingService service = ...
  service.print(new Document());  // How will you simulate 
                                  // throwing an exception?
} 

Personally, I would just avoid using singletons that way but rather introduce dependency injection, via Guice, Spring or Pico Container. That way you ensure existence of only one object, while not limiting yourself to not being able to mock the object out for example for tests.

少女七分熟 2024-08-03 20:07:51

使用基于枚举的单例不会导致任何性能损失,因为枚举实际上只是运行时的常规类。 我想您在类加载时可能会受到非常轻微的性能影响,因为系统可能正在执行正确性所需的所有正确初始化。 可序列化应该没有任何成本,因为这只是一个标签接口,仅检查您是否尝试序列化。 这确实是最著名的创建单例的方法!

You will not get any performance penalties for using an Enum-based singleton, as Enums are really just regular classes at runtime. I suppose you may get a very slight performance hit at classload time since the system may be doing all the correct initialization that are needed for correctness. There should be no cost to being Serializable, since that is just a tag interface, only check if you try to serialize. It really is the best known method for creating singletons!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文