Java中的Singleton模式和静态类有什么区别?

ces*_*sar 36 java design-patterns

单例与仅填充静态字段的类有何不同?

Str*_*ior 37

几乎每次我写一个静态类,我最终都希望我把它实现为一个非静态类.考虑:

  • 可以扩展非静态类.多态性可以节省大量的重复.
  • 非静态类可以实现一个接口,当您想要将实现与API分开时,该接口可以派上用场.

由于这两点,非静态类使得为依赖于它们的项目编写更可靠的单元测试成为可能.

然而,单例模式距离静态类只有半步之遥.你那种得到这些好处,但如果你是直接与其它类中通过`ClassName.Instance"访问它们,你要创建一个障碍访问这些好处.就像ph0enix指出的那样,使用依赖注入模式会更好.这样,可以告诉DI框架特定类是(或不是)单例.您可以获得模拟,单元测试,多态性以及更多灵活性的所有好处.

  • @nanosoft:当我说"静态类"时,我并不是指Java的["静态嵌套类"](http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html), OP正在询问,而是一个"只有静态字段的类".如果您考虑使用静态方法,无论它们所处的类的性质如何,我在此处所做的所有语句都适用:它们无法实现接口或被扩展.很抱歉我说"静态类"可能引起的任何混淆 - 这个术语在其他语言中更常见,但不适用于Java. (3认同)
  • 在java中,嵌套静态类可以扩展其他类(也可以被其他类扩展)并实现接口。检查 http://stackoverflow.com/a/37114702/1406510 (2认同)

ins*_*ode 12

让我总结一下:)

本质区别在于:单身的存在形式是一个对象,静态不是.这导致了以下几点:

  • 单身人士可以延长.静不.
  • 如果未正确实现,单例创建可能不是线程安全的.静不.
  • 单身人士可以作为一个对象传递.静不.
  • 单身人士可以被垃圾收集.静不.
  • Singleton比静态类更好!
  • 更多在这里,但我还没有意识到:)

最后但并非最不重要的是,每当你要实现一个单例时,请考虑重新设计你的想法,不使用这个上帝对象(相信我,你会倾向于将所有"有趣"的东西都放到这个类中)并使用正常的类命名为"上下文"或类似的东西.


JRL*_*JRL 5

单例可以懒惰地初始化.

  • 静态字段并不是非常懒惰的.当类加载器加载类时,将加载静态字段.可以编写单例,使得单例实例不在类加载时初始化,而是在单例实例的第一个请求上初始化.当然,单身人士最常用的方法并不是懒惰. (7认同)
  • 无论如何,静力学. (2认同)