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

时间:2022-01-31 13:21:10

This question already has an answer here:

这个问题在这里已有答案:

How is a singleton different from a class filled with only static fields?

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

12 个解决方案

#1


32  

Almost every time I write a static class, I end up wishing I had implemented it as a non-static class. Consider:

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

  • A non-static class can be extended. Polymorphism can save a lot of repetition.
  • 可以扩展非静态类。多态性可以节省大量的重复。

  • A non-static class can implement an interface, which can come in handy when you want to separate implementation from API.
  • 非静态类可以实现一个接口,当您想要将实现与API分开时,该接口可以派上用场。

Because of these two points, non-static classes make it possible to write more reliable unit tests for items that depend on them, among other things.

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

A singleton pattern is only a half-step away from static classes, however. You sort of get these benefits, but if you are accessing them directly within other classes via `ClassName.Instance', you're creating an obstacle to accessing these benefits. Like ph0enix pointed out, you're much better off using a dependency injection pattern. That way, a DI framework can be told that a particular class is (or is not) a singleton. You get all the benefits of mocking, unit testing, polymorphism, and a lot more flexibility.

然而,单例模式距离静态类只有半步之遥。您可以获得这些好处,但如果您通过“ClassName.Instance”直接在其他类中访问它们,那么您将无法获得访问这些优势的障碍。就像ph0enix指出的那样,使用依赖注入模式会更好。这样,可以告诉DI框架特定类是(或不是)单例。您可以获得模拟,单元测试,多态性和更多灵活性的所有好处。

#2


11  

Let's me sum up :)

让我总结一下:)

The essential difference is: The existence form of a singleton is an object, static is not. This conduced the following things:

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

  • Singleton can be extended. Static not.
  • 单身人士可以延长。静不。

  • Singleton creation may not be threadsafe if it isn't implemented properly. Static not.
  • 如果没有正确实现,单例创建可能不是线程安全的。静不。

  • Singleton can be passed around as an object. Static not.
  • Singleton可以作为对象传递。静不。

  • Singleton can be garbage collected. Static not.
  • 单身人士可以被垃圾收集。静不。

  • Singleton is better than static class!
  • Singleton比静态类更好!

  • More here but I haven't realized yet :)
  • 更多这里,但我还没有意识到:)

Last but not least, whenever you are going to implement a singleton, please consider to redesign your idea for not using this God object (believe me, you will tend to put all the "interesting" stuffs to this class) and use a normal class named "Context" or something like that instead.

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

#3


5  

A singleton can be initialized lazily, for one.

单例可以懒惰地初始化。

#4


3  

The difference is language independent. Singleton is by definition: "Ensure a class has only one instance and provide a global point of access to it. " a class filled with only static fields is not same as singleton but perhaps in your usage scenario they provide the same functionality. But as JRL said lazy initiation is one difference.

区别在于语言无关。 Singleton的定义是:“确保一个类只有一个实例并提供一个全局访问点。”一个只填充静态字段的类与单例不同,但可能在您的使用场景中它们提供相同的功能。但正如JRL所说,懒惰的启动是一个区别。

#5


3  

I think, significant thing is 'object' in object oriented programing. Except from few cases we should restrict to usage of static classes. That cases are:

我认为,重要的是面向对象编程中的“对象”。除少数情况外,我们应该限制使用静态类。那种情况是:

  1. When the create an object is meaningless. Like methods of java.lang.Math. We can use the class like an object. Because the behavior of Math class methods doesn't depend on the state of the objects to be created in this class.
  2. 当创建一个对象毫无意义时。就像java.lang.Math的方法一样。我们可以像对象一样使用类。因为Math类方法的行为不依赖于要在此类中创建的对象的状态。

  3. Codes to be used jointly by more than one object method, the codes that do not reach the object's variables and are likely to be closed out can be static methods
  4. 由多个对象方法共同使用的代码,未达到对象变量且可能被关闭的代码可以是静态方法

Another important thing is singleton is extensible. Singleton can be extended. In the Math class, using final methods, the creation and extension of the object of this class has been avoided. The same is true for the java.lang.System class. However, the Runtime class is a single object, not a static method. In this case you can override the inheritance methods of the Runtime class for different purposes.

另一个重要的事情是singleton是可扩展的。单身人士可以延长。在Math类中,使用final方法,避免了此类对象的创建和扩展。 java.lang.System类也是如此。但是,Runtime类是单个对象,而不是静态方法。在这种情况下,您可以为不同的目的覆盖Runtime类的继承方法。

You can delay the creation of a Singleton object until it is needed (lazy loading). However, for static method classes, there is no such thing as a condition. If you reach any static member of the class, the class will be loaded into memory.

您可以延迟创建Singleton对象,直到需要它(延迟加载)。但是,对于静态方法类,没有条件这样的东西。如果到达该类的任何静态成员,该类将被加载到内存中。

As a result, the most basic benefit to the static method class is that you do not have to create an object, but when used improperly, it will remove your code from being object-oriented.

因此,静态方法类的最基本的好处是您不必创建对象,但如果使用不当,它将删除您的代码,使其不受面向对象的影响。

#6


2  

At least you can more easily replace it by a mock or a stub for unit testing. But I am not a big fan of singletons for exactly the reason you are describing : it are global variables in disguise.

至少你可以更容易地用模拟或存根替换它来进行单元测试。但正如你所描述的那样,我不是单身人士的忠实粉丝:它是伪装的全球变量。

#7


2  

A singleton class will have an instance which generally is one and only one per classloader. So it can have regular methods(non static) ones and they can be invoked on that particular instance.

单例类将具有一个实例,该实例通常是每个类加载器只有一个实例。因此它可以有常规方法(非静态),并且可以在该特定实例上调用它们。

While a Class with only static methods, there is really no need in creating an instance(for this reason most of the people/frameworks make these kind of Util classes abstract). You will just invoke the methods on class directly.

虽然只有静态方法的类,但实际上没有必要创建实例(因此大多数人/框架都会使这些类的类抽象化)。您将直接在类上调用方法。

#8


2  

A singleton is a class with just one instance, enforced. That class may have state (yes I know static variables hold state), not all of the member variables or methods need be static.

单例是一个只有一个实例的类,强制执行。该类可能具有状态(是的,我知道静态变量保持状态),并非所有成员变量或方法都需要是静态的。

A variation would be a small pool of these objects, which would be impossible if all of the methods were static.

变体将是这些对象的小池,如果所有方法都是静态的,这将是不可能的。

#9


1  

The first thing that comes to mind is that if you want to use a class with only static methods and attributes instead of a singleton you will have to use the static initializer to properly initialise certain attributes. Example:

首先想到的是,如果你想使用只有静态方法和属性的类而不是单例,你必须使用静态初始化器来正确初始化某些属性。例:

class NoSingleton {
  static {
    //initialize foo with something complex that can't be done otherwise
  }
  static private foo;
}

This will then execute at class load time which is probably not what you want. You have more control over this whole shebang if you implement it as a singleton. However I think using singletons is not a good idea in any case.

然后,这将在类加载时执行,这可能不是您想要的。如果将它作为单身实现,你可以更好地控制整个shebang。但是我觉得在任何情况下使用单身都不是一个好主意。

#10


0  

NOTE: The examples are in C#, as that is what I am more familiar with, but the concept should apply to Java just the same.

注意:示例在C#中,因为这是我更熟悉的,但这个概念应该适用于Java。

Ignoring the debate on when it is appropriate to use Singleton objects, one primary difference that I am aware of is that a Singleton object has an instance that you can pass around.

忽略关于何时使用Singleton对象的争论,我所知道的一个主要区别是Singleton对象有一个可以传递的实例。

If you use a static class, you hard-wire yourself to a particular implementation, and there's no way to alter its behavior at run-time.

如果使用静态类,则需要将自己硬连接到特定实现,并且无法在运行时更改其行为。

Poor design using static class:

使用静态类设计不佳:

public class MyClass
{
   public void SomeMethod(string filename)
   {
      if (File.Exists(filename))
        // do something
   }
}

Alternatively, you could have your constructor take in an instance of a particular interface instead. In production, you could use a Singleton implementation of that interface, but in unit tests, you can simply mock the interface and alter its behavior to satisfy your needs (making it thrown some obscure exception, for example).

或者,您可以让构造函数接受特定接口的实例。在生产中,您可以使用该接口的Singleton实现,但在单元测试中,您可以简单地模拟接口并改变其行为以满足您的需求(例如,使其抛出一些模糊的异常)。

public class MyClass
{
   private IFileSystem m_fileSystem;

   public MyClass(IFileSystem fileSystem)
   {
      m_fileSystem = fileSystem;
   }

   public void SomeMethod(string filename)
   {
      if (m_fileSystem.FileExists(filename))
         // do something
   }
}

This is not to say that static classes are ALWAYS bad, just not a great candidate for things like file systems, database connections, and other lower layer dependencies.

这并不是说静态类总是坏的,不是文件系统,数据库连接和其他低层依赖项之类的好东西。

#11


0  

One of the main advantages of singletons is that you can implement interfaces and inherit from other classes. Sometimes you have a group of singletons that all provide similar functionality that you want to implement a common interface but are responsible for a different resource.

单例的一个主要优点是您可以实现接口并从其他类继承。有时你有一组单身人士都提供类似的功能,你想要实现一个共同的界面,但负责不同的资源。

#12


0  

Singleton Class : Singleton Class is class of which only single instance can exists per classloader.

Singleton类:Singleton类是每个类加载器只能存在单个实例的类。

Helper Class (Class with only static fields/methods) : No instance of this class exists. Only fields and methods can be directly accessed as constants or helper methods.

Helper类(仅包含静态字段/方法的类):不存在此类的实例。只能将字段和方法作为常量或辅助方法直接访问。

These few lines from this blog describes it nicely:

这篇博客中的这几行描述得非常好:

Firstly the Singleton pattern is very useful if you want to create one instance of a class. For my helper class we don't really want to instantiate any copy's of the class. The reason why you shouldn't use a Singleton class is because for this helper class we don't use any variables. The singleton class would be useful if it contained a set of variables that we wanted only one set of and the methods used those variables but in our helper class we don't use any variables apart from the ones passed in (which we make final). For this reason I don't believe we want a singleton Instance because we do not want any variables and we don't want anyone instantianting this class. So if you don't want anyone instantiating the class, which is normally if you have some kind of helper/utils class then I use the what I call the static class, a class with a private constructor and only consists of Static methods without any any variables.

首先,如果要创建一个类的实例,Singleton模式非常有用。对于我的助手类,我们并不想真正实例化该类的任何副本。你不应该使用Singleton类的原因是因为对于这个助手类我们不使用任何变量。如果单例类包含一组我们只需要一组变量并且方法使用这些变量但是在我们的帮助器类中我们不使用除传入的变量之外的任何变量(我们制作最终变量),这将是有用的。 。出于这个原因,我不相信我们想要一个单例实例,因为我们不想要任何变量,我们不希望任何人实例化这个类。因此,如果您不希望任何人实例化该类,通常如果您有某种类型的helper / utils类,那么我使用我称之为静态类的类,一个带有私有构造函数的类,并且只包含静态方法而没有任何类任何变量。

#1


32  

Almost every time I write a static class, I end up wishing I had implemented it as a non-static class. Consider:

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

  • A non-static class can be extended. Polymorphism can save a lot of repetition.
  • 可以扩展非静态类。多态性可以节省大量的重复。

  • A non-static class can implement an interface, which can come in handy when you want to separate implementation from API.
  • 非静态类可以实现一个接口,当您想要将实现与API分开时,该接口可以派上用场。

Because of these two points, non-static classes make it possible to write more reliable unit tests for items that depend on them, among other things.

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

A singleton pattern is only a half-step away from static classes, however. You sort of get these benefits, but if you are accessing them directly within other classes via `ClassName.Instance', you're creating an obstacle to accessing these benefits. Like ph0enix pointed out, you're much better off using a dependency injection pattern. That way, a DI framework can be told that a particular class is (or is not) a singleton. You get all the benefits of mocking, unit testing, polymorphism, and a lot more flexibility.

然而,单例模式距离静态类只有半步之遥。您可以获得这些好处,但如果您通过“ClassName.Instance”直接在其他类中访问它们,那么您将无法获得访问这些优势的障碍。就像ph0enix指出的那样,使用依赖注入模式会更好。这样,可以告诉DI框架特定类是(或不是)单例。您可以获得模拟,单元测试,多态性和更多灵活性的所有好处。

#2


11  

Let's me sum up :)

让我总结一下:)

The essential difference is: The existence form of a singleton is an object, static is not. This conduced the following things:

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

  • Singleton can be extended. Static not.
  • 单身人士可以延长。静不。

  • Singleton creation may not be threadsafe if it isn't implemented properly. Static not.
  • 如果没有正确实现,单例创建可能不是线程安全的。静不。

  • Singleton can be passed around as an object. Static not.
  • Singleton可以作为对象传递。静不。

  • Singleton can be garbage collected. Static not.
  • 单身人士可以被垃圾收集。静不。

  • Singleton is better than static class!
  • Singleton比静态类更好!

  • More here but I haven't realized yet :)
  • 更多这里,但我还没有意识到:)

Last but not least, whenever you are going to implement a singleton, please consider to redesign your idea for not using this God object (believe me, you will tend to put all the "interesting" stuffs to this class) and use a normal class named "Context" or something like that instead.

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

#3


5  

A singleton can be initialized lazily, for one.

单例可以懒惰地初始化。

#4


3  

The difference is language independent. Singleton is by definition: "Ensure a class has only one instance and provide a global point of access to it. " a class filled with only static fields is not same as singleton but perhaps in your usage scenario they provide the same functionality. But as JRL said lazy initiation is one difference.

区别在于语言无关。 Singleton的定义是:“确保一个类只有一个实例并提供一个全局访问点。”一个只填充静态字段的类与单例不同,但可能在您的使用场景中它们提供相同的功能。但正如JRL所说,懒惰的启动是一个区别。

#5


3  

I think, significant thing is 'object' in object oriented programing. Except from few cases we should restrict to usage of static classes. That cases are:

我认为,重要的是面向对象编程中的“对象”。除少数情况外,我们应该限制使用静态类。那种情况是:

  1. When the create an object is meaningless. Like methods of java.lang.Math. We can use the class like an object. Because the behavior of Math class methods doesn't depend on the state of the objects to be created in this class.
  2. 当创建一个对象毫无意义时。就像java.lang.Math的方法一样。我们可以像对象一样使用类。因为Math类方法的行为不依赖于要在此类中创建的对象的状态。

  3. Codes to be used jointly by more than one object method, the codes that do not reach the object's variables and are likely to be closed out can be static methods
  4. 由多个对象方法共同使用的代码,未达到对象变量且可能被关闭的代码可以是静态方法

Another important thing is singleton is extensible. Singleton can be extended. In the Math class, using final methods, the creation and extension of the object of this class has been avoided. The same is true for the java.lang.System class. However, the Runtime class is a single object, not a static method. In this case you can override the inheritance methods of the Runtime class for different purposes.

另一个重要的事情是singleton是可扩展的。单身人士可以延长。在Math类中,使用final方法,避免了此类对象的创建和扩展。 java.lang.System类也是如此。但是,Runtime类是单个对象,而不是静态方法。在这种情况下,您可以为不同的目的覆盖Runtime类的继承方法。

You can delay the creation of a Singleton object until it is needed (lazy loading). However, for static method classes, there is no such thing as a condition. If you reach any static member of the class, the class will be loaded into memory.

您可以延迟创建Singleton对象,直到需要它(延迟加载)。但是,对于静态方法类,没有条件这样的东西。如果到达该类的任何静态成员,该类将被加载到内存中。

As a result, the most basic benefit to the static method class is that you do not have to create an object, but when used improperly, it will remove your code from being object-oriented.

因此,静态方法类的最基本的好处是您不必创建对象,但如果使用不当,它将删除您的代码,使其不受面向对象的影响。

#6


2  

At least you can more easily replace it by a mock or a stub for unit testing. But I am not a big fan of singletons for exactly the reason you are describing : it are global variables in disguise.

至少你可以更容易地用模拟或存根替换它来进行单元测试。但正如你所描述的那样,我不是单身人士的忠实粉丝:它是伪装的全球变量。

#7


2  

A singleton class will have an instance which generally is one and only one per classloader. So it can have regular methods(non static) ones and they can be invoked on that particular instance.

单例类将具有一个实例,该实例通常是每个类加载器只有一个实例。因此它可以有常规方法(非静态),并且可以在该特定实例上调用它们。

While a Class with only static methods, there is really no need in creating an instance(for this reason most of the people/frameworks make these kind of Util classes abstract). You will just invoke the methods on class directly.

虽然只有静态方法的类,但实际上没有必要创建实例(因此大多数人/框架都会使这些类的类抽象化)。您将直接在类上调用方法。

#8


2  

A singleton is a class with just one instance, enforced. That class may have state (yes I know static variables hold state), not all of the member variables or methods need be static.

单例是一个只有一个实例的类,强制执行。该类可能具有状态(是的,我知道静态变量保持状态),并非所有成员变量或方法都需要是静态的。

A variation would be a small pool of these objects, which would be impossible if all of the methods were static.

变体将是这些对象的小池,如果所有方法都是静态的,这将是不可能的。

#9


1  

The first thing that comes to mind is that if you want to use a class with only static methods and attributes instead of a singleton you will have to use the static initializer to properly initialise certain attributes. Example:

首先想到的是,如果你想使用只有静态方法和属性的类而不是单例,你必须使用静态初始化器来正确初始化某些属性。例:

class NoSingleton {
  static {
    //initialize foo with something complex that can't be done otherwise
  }
  static private foo;
}

This will then execute at class load time which is probably not what you want. You have more control over this whole shebang if you implement it as a singleton. However I think using singletons is not a good idea in any case.

然后,这将在类加载时执行,这可能不是您想要的。如果将它作为单身实现,你可以更好地控制整个shebang。但是我觉得在任何情况下使用单身都不是一个好主意。

#10


0  

NOTE: The examples are in C#, as that is what I am more familiar with, but the concept should apply to Java just the same.

注意:示例在C#中,因为这是我更熟悉的,但这个概念应该适用于Java。

Ignoring the debate on when it is appropriate to use Singleton objects, one primary difference that I am aware of is that a Singleton object has an instance that you can pass around.

忽略关于何时使用Singleton对象的争论,我所知道的一个主要区别是Singleton对象有一个可以传递的实例。

If you use a static class, you hard-wire yourself to a particular implementation, and there's no way to alter its behavior at run-time.

如果使用静态类,则需要将自己硬连接到特定实现,并且无法在运行时更改其行为。

Poor design using static class:

使用静态类设计不佳:

public class MyClass
{
   public void SomeMethod(string filename)
   {
      if (File.Exists(filename))
        // do something
   }
}

Alternatively, you could have your constructor take in an instance of a particular interface instead. In production, you could use a Singleton implementation of that interface, but in unit tests, you can simply mock the interface and alter its behavior to satisfy your needs (making it thrown some obscure exception, for example).

或者,您可以让构造函数接受特定接口的实例。在生产中,您可以使用该接口的Singleton实现,但在单元测试中,您可以简单地模拟接口并改变其行为以满足您的需求(例如,使其抛出一些模糊的异常)。

public class MyClass
{
   private IFileSystem m_fileSystem;

   public MyClass(IFileSystem fileSystem)
   {
      m_fileSystem = fileSystem;
   }

   public void SomeMethod(string filename)
   {
      if (m_fileSystem.FileExists(filename))
         // do something
   }
}

This is not to say that static classes are ALWAYS bad, just not a great candidate for things like file systems, database connections, and other lower layer dependencies.

这并不是说静态类总是坏的,不是文件系统,数据库连接和其他低层依赖项之类的好东西。

#11


0  

One of the main advantages of singletons is that you can implement interfaces and inherit from other classes. Sometimes you have a group of singletons that all provide similar functionality that you want to implement a common interface but are responsible for a different resource.

单例的一个主要优点是您可以实现接口并从其他类继承。有时你有一组单身人士都提供类似的功能,你想要实现一个共同的界面,但负责不同的资源。

#12


0  

Singleton Class : Singleton Class is class of which only single instance can exists per classloader.

Singleton类:Singleton类是每个类加载器只能存在单个实例的类。

Helper Class (Class with only static fields/methods) : No instance of this class exists. Only fields and methods can be directly accessed as constants or helper methods.

Helper类(仅包含静态字段/方法的类):不存在此类的实例。只能将字段和方法作为常量或辅助方法直接访问。

These few lines from this blog describes it nicely:

这篇博客中的这几行描述得非常好:

Firstly the Singleton pattern is very useful if you want to create one instance of a class. For my helper class we don't really want to instantiate any copy's of the class. The reason why you shouldn't use a Singleton class is because for this helper class we don't use any variables. The singleton class would be useful if it contained a set of variables that we wanted only one set of and the methods used those variables but in our helper class we don't use any variables apart from the ones passed in (which we make final). For this reason I don't believe we want a singleton Instance because we do not want any variables and we don't want anyone instantianting this class. So if you don't want anyone instantiating the class, which is normally if you have some kind of helper/utils class then I use the what I call the static class, a class with a private constructor and only consists of Static methods without any any variables.

首先,如果要创建一个类的实例,Singleton模式非常有用。对于我的助手类,我们并不想真正实例化该类的任何副本。你不应该使用Singleton类的原因是因为对于这个助手类我们不使用任何变量。如果单例类包含一组我们只需要一组变量并且方法使用这些变量但是在我们的帮助器类中我们不使用除传入的变量之外的任何变量(我们制作最终变量),这将是有用的。 。出于这个原因,我不相信我们想要一个单例实例,因为我们不想要任何变量,我们不希望任何人实例化这个类。因此,如果您不希望任何人实例化该类,通常如果您有某种类型的helper / utils类,那么我使用我称之为静态类的类,一个带有私有构造函数的类,并且只包含静态方法而没有任何类任何变量。