Java 单例程序中静态语句的使用和流程
我知道有很多关于单身模式的问题。但这里我想知道的是关于输出的内容,可能还包括“静态”在Java中的工作方式Java 单例程序中静态语句的使用和流程,java,static,singleton,Java,Static,Singleton,我知道有很多关于单身模式的问题。但这里我想知道的是关于输出的内容,可能还包括“静态”在Java中的工作方式 public class Singleton { private static Singleton currentSingleton = new Singleton(); public static Singleton getSingleton() { return currentSingleton; } private Singlet
public class Singleton {
private static Singleton currentSingleton = new Singleton();
public static Singleton getSingleton() {
return currentSingleton;
}
private Singleton() {
System.out.println("Singleton private constructor...");
}
public static void main(String[] args) {
System.out.println("Main method...");
}
}
这是运行代码的输出
单例私有构造函数<主要方法
当我调试这段代码时,控件首先进入第行
System.out.println(“单例私有构造函数…”)
并打印。
(此时专用静态变量currentSingleton仍然为空)然后转到第行
private static Singleton currentSingleton=new Singleton()代码>
然后初始化私有变量。
最后,它转到main()方法并打印
我的问题是:
为什么它首先打印私有构造函数中的“单例私有构造函数…”。
我认为控件应该首先转到main()方法,因为它是入口点。此外,我没有在任何地方创建任何实例(变量初始化除外)
稍后它将转到静态变量实例化行(此时currentSingleton=null)
private static Singleton currentSingleton=new Singleton()代码>
虽然currentSingleton在这里得到一个值,但为什么不再次调用构造函数呢
我主要想知道这个程序的控制流程。在类中的main方法被正确初始化之前(即静态字段和静态块已被计算),您不能调用它。初始化时,通过调用私有构造函数创建singleton的实例。稍后调用main方法
所讨论的类有一个静态字段,您可以向其赋值。由于该字段是静态的,因此必须先对其进行初始化,然后才能在任何上下文中使用该类,也就是说,它必须接收一个值。在这种情况下,它的值恰好是同一类的实例。这就是在类初始化期间触发私有构造函数的原因
如果您想深入研究该过程并更好地理解它,请参阅。更具体地说,在第12.4节中,您将看到更多详细信息。每当控件第一次出现在任何类上时,所有静态初始化都首先发生。这就是为什么在调用静态对象的构造函数之前先实例化它。在控件访问main()方法之前,需要初始化该类。由于您使用声明内联初始化了currentSingleton
,因此在类加载期间,此初始化发生在main()之前。您应该将其声明为final
private static final Singleton currentSingleton = new Singleton();
初始化值为编译时常量的接口的最终类变量和字段
回答你的两个问题
如果声明符用于类变量(即静态字段),则在初始化类时,变量初始值设定项将被求值并执行一次赋值(§12.4.2)
类首先由JVM的类加载器加载和初始化。JVM在初始化时扫描类(Singleton),并在初始化时初始化第一行中的静态变量。该变量调用构造函数并打印其中的行。初始化类后,它将调用main方法,从而打印其中的语句。由于必须初始化currentSingleton
静态字段,因此new Singleton()
语句是第一个执行的语句;这意味着为正在创建的单例对象分配内存,并在将结果对象分配给字段变量之前执行其构造函数。
这就是System.out.println(“单例私有构造函数…”)的原因代码>分配前正在执行的行。
此外,静态字段初始化会在类被引用时立即发生,调用Singleton类的main函数意味着引用它,这就是在main方法之前执行初始化的原因。为了澄清:,直到它被正确初始化为止。
->这里是类对象,好的,第一个类应该正确初始化,所以它将调用行private static Singleton currentSingleton=new Singleton();然后它应该调用构造函数并打印语句。但当我调试它时,控件首先进入私有构造函数,打印,然后初始化私有静态变量。这就是我感到困惑的原因。@amit这个类有一个静态字段,您可以将一个值赋给它。由于该字段是静态的,因此必须使用类对其进行初始化,也就是说,它必须接收一个值。在这种情况下,它的值恰好是同一类的实例。这就是在类初始化期间触发私有构造函数的原因。是的,我看错了。我在it=class对象
中的意思是:在调用main()
之前,必须实例化class对象。(由此可以得到,为了让它发生,赋值currentSingleton=new Singleton();
必须发生,这反过来又实例化了对象)。(顺便说一句,我已经给出了答案。)@amit你可能需要阅读更多细节。