我无法理解以下代码的执行。我想遵循Java程序,以便我能够理解所有内容如何协同工作。我在 Eclipse 中增加了断点,但它没有解释原因。代码如下:
public class Sequence {
public Sequence() {
System.out.print("c ");
}
{
System.out.print("y ");
}
public static void main(String[] args) {
new Sequence().go();
}
void go() {
System.out.print("g ");
}
static {
System.out.print("x ");
}
}
代码的输出是x y c g
。有人可以解释为什么会这样吗?我以为程序入口点public static void main
但似乎static
先执行?
static
块在main
开始之前执行,因此x
打印。
然后我们进入主,我们打电话
new Sequence().go();
它调用Sequence
构造函数。根据静态块,在调用 Sequence
构造函数之前(因此在初始化新的 Sequence
对象之前),实例块(写在大括号内的块)被执行,因此y
被打印出来。
然后构造函数调用打印c
.
最后,go()
方法在新创建的对象上调用,因此g
打印。
所以完整的输出将是
x y c g
JLS 在这里很有帮助,准确地说是第 12 章。
首先,static
块将运行。当类由ClassLoader
加载时,将发生这种情况。
然后main
将运行,这由 JVM 执行以启动应用程序。
然后,当您调用 new Sequence()
时,将执行您的构造函数。编译器会将实例初始化器(大括号中的位)拉到构造函数的顶部(在对超类构造函数的隐式调用之后)。因此,大括号中的位首先运行,然后运行构造函数中的代码。
最后调用方法go()
。
所以代码的输出是x y c g
类加载之后和任何方法之前执行静态块。Main 方法是任何程序的入口点,但它是静态类初始化的方法。
在你的类中你用过
//constructor
public Sequence() {
System.out.print("c ");
}
//instance init block
{
System.out.print("y ");
}
//method
void go() {
System.out.print("g ");
}
//static init block
static {
System.out.print("x ");
}
-> 初始化块按其出现的顺序执行。
->静态初始化块在首次加载类时运行一次。
-> 每次创建类实例时,实例初始化块都会运行。
-> 实例初始化块在构造函数调用 super() 之后运行。
->构造函数在创建实例后运行。
根据您获得的所有规则,如预期的那样x y c g
输出
第一个 jvm 在应用程序启动时加载静态块。所以首先执行静态块。 然后开始执行主方法。
{
System.out.print("y ");
}
是构造函数块,它将被复制到每个构造函数,因此当您实例化类时,每次都会调用它。 点击这里
步骤:
我。加载类时,首先执行静态块。
ii. 每次实例化该类的对象时,初始化块 即
{
System.out.print("y ");
}
is executed(every time) and after that the time of constructor comes to be executed.
iii. 对象创建完成后,执行 go() 方法。 因此输出。