我有这样的代码:
class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Singleton() {
System.out.println("Singleton constructed.");
}
public static Singleton getInstance() {
return INSTANCE;
}
}
当我们没有任何其他getInstance的静态方法时,是否初始化了此单例惰性?据我所知,类只在某些情况下初始化,比如:
(Surce:http://javarevisited.blogspot.com/2012/07/when-class-loading-initialization-java-example.html#ixzz4IjIe2Rf5)
因此,当唯一的静态方法是getInstance
并且构造函数是私有的时,除了使用getInstance方法(除了反射)之外,没有任何其他方式初始化Singleton类的可能性。所以只有在我们需要的时候才会创建对象,所以这是一个懒惰的初始化,对吗?或者我错过了什么?
编辑:我错了。类不是通过引用来加载的,如下所示:
System.out.println(Singleton.class);
创建实例、引用静态成员或以编程方式加载时,类加载器会立即加载类:
Class<?> clazz = Class.forName("Singleton"); // fully qualified classname
上面的语句导致类被加载,所有静态成员和块都将按照类中出现的顺序进行处理。在示例类中,这将导致初始化实例变量(并将消息打印到System.out)。这证明您的方法不能保证延迟加载。
实现延迟加载单例的更好方法是使用单例持有人模式:
class Singleton {
private static class Holder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton() {
// hide constructor
}
public static Singleton getInstance() {
return Holder.INSTANCE;
}
}
它是立即初始化的,所以不,不是。通常,延迟初始化意味着您在尝试实际检索时对其进行初始化,但字段尚未初始化。
懒惰初始化与类初始化无关——它与包含在其中的字段有关。在您的情况下,一旦类被加载,该字段将立即初始化。
您的示例适合使用惰性初始化:
class Singleton {
private static Singleton INSTANCE;
private Singleton() {
System.out.println("Singleton constructed.");
}
public static Singleton getInstance() {
if(INSTANCE == null) {
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
这将仅在实际请求时构造单例,而不仅仅是在内存中加载singleton
类时。在您的情况下,如果它加载到内存中,那么它的静态
字段将被初始化(包括您的单例字段)。
您提到了静态方法和私有构造函数。添加另一个静态字段,类似于:
static int NUMBER = 13;
在你的单身班。在其他类别的主要方法中:
System.out.println(Singleton.NUMBER);
然后,您将看到您的单例不是惰性初始化的。
但是,当您的字段是静态最终字段时:
static final int NUMBER = 13;
单例是惰性初始化的。
更重要的是,当您在Singleton类中添加静态和非静态初始化块时:
{
System.out.println("non-static");
}
static {
System.out.println("static");
}
顺序是:非静态,私有构造函数,然后是静态的,因为您正在将一个对象作为静态字段的值进行设置。所以,这是非常棘手的:)
总之,在某些情况下,您的单例可能被认为是延迟初始化的,但通常情况下并非如此。
问题内容: 如果我在代码中使用如下语句 它将数组初始化为特定的东西吗?(例如0)我似乎记得此文件记录在某处,但我不确定要搜索什么。 问题答案: JLS说,在15.10数组创建表达式中 […]创建具有指定长度的一维数组,并将数组的每个组件初始化为其默认值 在4.12.5变量的初始值处表示: 对于type ,默认值为零,即。
问题内容: 我需要使用类似于php的isset函数的东西。我知道php和java截然不同,但是php是我先前类似编程知识的唯一基础。是否有某种方法可以返回一个布尔值,用于确定实例变量是否已初始化。例如… 到目前为止,我遇到了这个问题,当我的程序试图隐藏或删除尚未构造的对象时,出现运行时错误。 问题答案: 假设您对是否已为变量 明确赋值 感兴趣,答案是“不是真的”。但绝对的字段(实例变量或类变量)尚
我想知道是否有一种方法可以检查变量是否已经初始化。例如:
我想知道是否有办法检查变量是否已初始化。例如:
问题内容: 哪种方法检查变量是否已初始化是更好/正确的方法?(假设变量可以容纳任何内容(字符串,整数,对象,函数等)) 要么 要么 问题答案: 该运营商将检查变量真的不确定。 该运营商,不同于其他运营商,不会抛出 的ReferenceError 与未声明的变量使用时例外。 但是,请注意将返回。我们必须小心避免将变量初始化为的错误。为了安全起见,我们可以改用以下方法:
问题内容: 当我测试新插件时,不断抛出异常:java.lang.IllegalArgumentException:插件已初始化!请帮忙!这是代码: 我知道您只应该为每个插件声明一个JavaPlugin类,我认为我正在这样做。但它一直在说: 我真的需要测试此插件,看看它是否有效,任何帮助将不胜感激!谢谢! 问题答案: stacktrace清楚地指出了问题出在哪里。什么是堆栈跟踪,如何使用它来调试应用