Java中初始化块和构造函数的执行顺序
先决条件:静态块,初始化块,构造函数
在Java程序中,可以对方法、构造函数和初始化块执行操作。
实例初始化块:IIB 用于初始化实例变量。 IIB 在构造函数之前执行。每次创建类的对象时它们都会运行。
Initializer 块:包含在创建实例时始终执行的代码。它用于声明/初始化类的各种构造函数的公共部分。
构造函数:用于初始化对象的状态。与方法一样,构造函数也包含在创建对象时执行的语句(即指令)集合。
Java中初始化块和构造函数的执行顺序
- 每当类第一次在 JVM 中加载时,静态初始化块就会运行
- 初始化块按照它们在程序中出现的顺序运行。
- 每当初始化类并且在调用构造函数之前执行实例初始化块。它们通常放置在大括号内的构造函数上方。
// Java code to illustrate order of
// execution of constructors, static
// and initialization blocks
class GFG {
GFG(int x)
{
System.out.println("ONE argument constructor");
}
GFG()
{
System.out.println("No argument constructor");
}
static
{
System.out.println("1st static init");
}
{
System.out.println("1st instance init");
}
{
System.out.println("2nd instance init");
}
static
{
System.out.println("2nd static init");
}
public static void main(String[] args)
{
new GFG();
new GFG(8);
}
}
输出
1st static init
2nd static init
1st instance init
2nd instance init
No argument constructor
1st instance init
2nd instance init
ONE argument constructor
注意:如果有两个或多个静态/初始化程序块,那么它们将按照它们在源代码中出现的顺序执行。
现在,预测以下程序的输出 -
// A tricky Java code to predict the output
// based on order of
// execution of constructors, static
// and initialization blocks
class MyTest {
static
{
initialize();
}
private static int sum;
public static int getSum()
{
initialize();
return sum;
}
private static boolean initialized = false;
private static void initialize()
{
if (!initialized) {
for (int i = 0; i < 100; i++)
sum += i;
initialized = true;
}
}
}
public class GFG {
public static void main(String[] args)
{
System.out.println(MyTest.getSum());
}
}
输出:
9900
解释:
- 初始化函数中的循环从 0 到 99。考虑到这一点,您可能会认为程序会打印从 0 到 99 的数字的总和。因此 sum 是 99 × 100 / 2 或 4、950。然而,该程序, 不以为然。它打印9900 ,完全是这个值的两倍。
- 要了解它的行为,让我们跟踪它的执行情况。GFG.main 方法调用 MyTest.getSum。在执行 getSum 方法之前,VM 必须初始化类 MyTest。类初始化按照它们在源代码中出现的顺序执行静态初始化程序。
- MyTest 类有两个静态初始化器:类顶部的静态块和已初始化的静态字段的初始化。该块首先出现。它调用方法initialize,该方法测试已初始化的字段。由于尚未为该字段分配任何值,因此它具有默认布尔值 false。
- 类似地,sum 的默认 int 值是 0。因此,initialize 方法执行您所期望的操作,将 4, 950 添加到 sum 并将 initialized 设置为 true。静态块执行后,已初始化字段的静态初始化器将其设置回 false,从而完成 MyTest 的类初始化。不幸的是,sum 现在包含 4950,但 initialized 包含 false。
- 然后 GFG 类中的 main 方法调用 MyTest.getSum,后者又调用 initialize 方法。因为初始化标志为假,所以initializeIf方法进入了它的循环,在sum的值上再增加4, 950,将它的值增加到9, 900。getSum方法返回这个值,程序打印出来