静态类和单例模式之间存在什么实际的区别?
两者都可以在没有实例化的情况下调用,两者都只提供一个“实例”,而且都不是线程安全的。还有其他区别吗?
静态类和单例模式之间存在什么实际的区别?
两者都可以在没有实例化的情况下调用,两者都只提供一个“实例”,而且都不是线程安全的。还有其他区别吗?
当前回答
与静态类的区别
JDK有单例和静态的例子,一方面java.lang.Math是带有静态方法的最终类,另一方面java.lang.Runtime是单例类。
单例的优点
如果您需要维护状态,那么单例模式比静态类更好,因为在静态类中维护状态会导致错误,特别是在并发环境中,如果没有多个线程进行适当的同步并行修改,则可能会导致竞争条件。如果Singleton类是一个沉重的对象,那么它可以被延迟加载,但静态类没有这样的优势,总是急切地加载。使用singleton,您可以使用继承和多态性来扩展基类、实现接口并提供不同的实现。由于Java中的静态方法不能被重写,它们会导致灵活性。另一方面,您可以通过扩展singleton类来重写它中定义的方法。
静态类的缺点
为单例编写单元测试比静态类更容易,因为只要需要单例,就可以传递模拟对象。
静态类的优点
静态类提供了比单例更好的性能,因为静态方法是在编译时绑定的。
单例模式有几种实现方式,每种实现方式都有优缺点。
Eager加载单例双重检查锁定单例按需初始化持有者习惯用法基于枚举的单例
详细描述每一个都太冗长了,所以我只需要链接到一篇好文章-你想知道的关于Singleton的所有信息
其他回答
扩展Jon Skeet的答案
单例和一堆静态方法之间的最大区别是,单例可以实现接口(或从有用的基类派生,尽管这是不太常见的IME),因此您可以将单例作为“另一个”实现来传递。
当单元测试一个类时,单体更容易处理。无论您将单例作为参数(构造函数、setter或方法)传递到何处,您都可以替换单例的一个被嘲笑或存根的版本。
主要区别在于:
Singleton有一个实例/对象,而静态类是一堆静态方法Singleton可以在静态时通过接口进行扩展班级不可能。Singleton可以继承,它支持另一方面,静态类不能继承SOLID原则我们需要自己做出改变。Singleton对象可以传递给方法,而静态类作为它没有实例不能作为参数传递
静态类不适用于任何需要状态的对象。它对于将一堆函数放在一起非常有用,例如Math(或项目中的Utils)。所以类名只是给了我们一个线索,我们可以在哪里找到函数,而不是更多。
Singleton是我最喜欢的模式,我用它在一个点上管理一些东西。它比静态类更灵活,可以保持其状态。它可以实现接口,从其他类继承并允许继承。
我在静态和单例之间选择的规则:
如果有一堆函数应该保持在一起,那么静态就是选择。任何其他需要对某些资源进行单一访问的内容都可以作为单例实现。
是什么让你说单例或静态方法都不是线程安全的?通常,这两者都应该实现为线程安全的。
单例和一堆静态方法之间的最大区别是,单例可以实现接口(或从有用的基类派生,尽管在我的经验中这不太常见),因此您可以将单例作为“另一个”实现来传递。
单个对象存储在堆中,但静态对象存储在堆栈中。我们可以克隆(如果设计器不允许)单例对象,但不能克隆静态类对象.单类遵循OOP(面向对象原则),静态类则不遵循。我们可以用Singleton类实现接口,但类的静态方法(例如C#静态类)不能。