我读了很多关于Singleton的文章,其中大多数作者都说Java中Singleton的这种变体:
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
不是LAZY ( 然后 是 EAGER )。
但是我不明白为什么,Singleton()
构造Singleton
函数只会在类初始化时被调用。我知道几个可以触发类初始化的原因:
new
与构造函数一起使用(但在这种情况下,构造函数是私有的)。Class.forName("Singleton")
。因此,这里我们的对象将仅在使用静态方法getInstance()
(我想它仍然是 LAZY
初始化)和反射的情况下创建(但是反射可能会破坏很多Singleton变量,除非如此enum
)。
也许我看不到明显的东西,请给我解释,我哪里错了?
基本上,这是懒惰的问题。这是懒在直到类初始化它不会构建单,但它是在渴望有 可能 是情况下,您要使用的类没有初始化的单身本身。
例如:
public final class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
public static void sayHello() {
System.out.println("Hello!");
}
}
调用Singleton.sayHello()
将实例化单例,即使我们不希望它…也因此没有那么懒。
您可以使用嵌套类型来解决此问题:
public final class Singleton {
private Singleton() {}
public static Singleton getInstance() {
return Holder.instance;
}
public static void sayHello() {
System.out.println("Hello!");
}
private static class Holder {
private static final Singleton instance = new Singleton();
}
}
现在Singleton.Holder
将仅通过使用getInstance
方法进行初始化。它是惰性的并且是线程安全的,没有锁定。
以我的经验,通常单例类的 唯一 静态方法是getInstance
方法,在这种情况下,它们是等效的(例如,假设您不使用反射以某种方式初始化类型)。
问题内容: 为什么Java有瞬态字段? 问题答案: 在中关键字用于指示字段不应该是系列化的一部分(这意味着保存,像一个文件)的过程。 从Java语言规范,Java SE 7中版,第8.3.1.3节。transient领域: 可以标记变量transient以指示它们不是对象持久状态的一部分。 例如,你可能具有从其他字段派生的字段,并且仅应以编程方式进行操作,而不要通过序列化来保持状态。 这是一个包含
问题内容: 在大学里学习时,我不得不做一些难看的Java基础知识,例如不使用封装就可以工作,同一类中的主要方法等。(我不想在Java样式指南上展开讨论,我只是想澄清一下,我不会在大学以外写这样的东西) 我偶然发现了一种我无法向自己解释的行为: 为什么这段代码可以编译并正确运行?我怎么可能访问私有字段?由于主类位于同一类中,因此行为异常? 问题答案: 由于静态方法是类的成员,因此可以访问中的任何私有
问题内容: 我想使用反射对单元测试设置私有字段的值。 问题是,该字段是静态的。 这是我正在从事的工作: 我意识到这可能已经在SO上得到了解答,但是我的搜索并没有找到答案… 问题答案: 基本上,问题是您的实用程序方法,该方法假设您有一个实例。设置私有静态字段相当容易- 与实例字段完全相同,但您指定为实例除外。不幸的是,您的实用程序方法使用实例来获取类,并要求该类为非null … 我会回应汤姆的警告:
问题内容: 虽然无法使用来访问静态字段,但是如果我想记录一些应该是静态的内容(例如,创建的InnerClass对象的数量),则使该字段静态化将很有帮助。那么,为什么 Java禁止内部类中的静态字段/方法呢? 编辑:我知道如何使编译器对静态嵌套类(或静态内部类)感到满意,但是我想知道的是为什么Java禁止从语言设计和内部类(或普通内部类)内部的静态字段/方法实施方面,如果有人对此有更多了解。 问题答
问题内容: 如果将变量声明为,那么我可以从任意位置访问它。我还知道,静态成员由类的所有实例共享,并且不在每个实例中重新分配。 声明变量与声明变量有什么不同吗? 在这两种情况下,都不能以任何其他类或从任何其他类访问它。 将变量声明为静态是否会赋予它其他特殊属性? 问题答案: 当然,可以将其作为,但只能从定义它的类内部进行访问-这是因为它被定义为。 或变量通常用于常量。例如,许多人不喜欢在代码中“硬编
问题内容: 这是指帖子 ..无法回复或评论任何这样创建的新帖子。为什么是我的 发出警告-应该以静态方式访问静态字段MyUnits.MILLSECONDS吗?谢谢。 问题答案: 因为当您访问静态字段时,您应该在类(或本例中为枚举)上执行此操作。如 不在实例中 编辑 要解决 为什么这样 的问题:在Java中,当您将声明为时,就是说它是类的成员,而不是对象(因此为什么只有一个)。因此,在对象上访问它是没