Java 中的单例模式和静态类有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3532161/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the difference between a Singleton pattern and a static class in Java?
提问by cesar
How is a singleton different from a class filled with only static fields?
单例与仅填充静态字段的类有何不同?
采纳答案by StriplingWarrior
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 ofget 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 框架某个特定类是(或不是)单例。您可以获得模拟、单元测试、多态性和更多灵活性的所有好处。
回答by Peter Tillemans
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.
至少您可以更轻松地将其替换为模拟或存根以进行单元测试。但是,正如您所描述的原因,我并不是单身人士的忠实粉丝:它是伪装的全局变量。
回答by JRL
A singleton can be initialized lazily, for one.
一个单例可以懒惰地初始化,例如。
回答by JRL
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.
一个变体是这些对象的一个小池,如果所有方法都是静态的,这是不可能的。
回答by Numenor
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.
区别在于语言无关。单例的定义是:“确保一个类只有一个实例并提供对其的全局访问点。”仅填充静态字段的类与单例不同,但在您的使用场景中,它们可能提供相同的功能。但正如 JRL 所说,懒惰的启动是一个区别。
回答by Teja Kantamneni
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.
虽然一个只有静态方法的类,但实际上没有必要创建一个实例(因此大多数人/框架使这些 Util 类抽象)。您将直接调用类上的方法。
回答by Raoul Duke
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。但是我认为在任何情况下使用单例都不是一个好主意。
回答by jeremyalan
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).
或者,您可以让构造函数接收特定接口的实例。在生产中,您可以使用该接口的单例实现,但在单元测试中,您可以简单地模拟接口并更改其行为以满足您的需要(例如,使其抛出一些模糊的异常)。
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.
这并不是说静态类总是不好的,只是不适合文件系统、数据库连接和其他较低层依赖项等内容。
回答by doobop
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.
单例的主要优点之一是您可以实现接口并从其他类继承。有时,您有一组单例,它们都提供类似的功能,您希望实现一个通用接口,但负责不同的资源。
回答by YoK
Singleton Class :Singleton Class is class of which only single instance can exists per classloader.
单例类:单例类是每个类加载器只能存在单个实例的类。
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 blogdescribes 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 类的原因是因为对于这个辅助类,我们不使用任何变量。如果单例类包含一组我们只想要一组变量并且方法使用这些变量,但在我们的助手类中,除了传入的变量(我们将其设为 final)之外,我们不使用任何变量,那么它会很有用. 出于这个原因,我不相信我们想要一个单例实例,因为我们不想要任何变量,我们也不希望任何人实例化这个类。所以如果你不想让任何人实例化这个类,