java 初始化及执行顺序

规则1:在类第一次加载的时候,将会进行静态域的初始化:

  1. 将所有的静态数据域初始化为默认值(0、false 和 null,若标志为final则直接为其赋值“=”后的数据)

  2. 按照在类中定义的顺序依次执行静态初始化语句和静态初始化块

规则2:调用构造器的具体处理步骤:

  1. 将所有的数据域初始化为默认值(0、false 和 null)

  2. 按照在类中定义的顺序依次执行初始化语句和初始化块

  3. 如果构造器调用的其他的构造器,则转而执行另一构造器

  4. 执行构造器主体

注:静态方法和实例方法均在调用时立即加载;

类加载的时机只需简单的知道是在调用构造器之前且只有一次,具体的类加载过程这里就不说了,否则就跑得太偏了。

测试用例如下:

public class Test {

public static int k = 0;
public static Test t1 = new Test(“t1”);
public static Test t2 = new Test(“t2”);
public static int i = print(“i”);
public static int n = 99;
private int a = 0;
public int j = print(“j”);
{
print(“构造块”);
}
static {
print(“静态块”);
}

public Test(String str) {
System.out.println((++k) + “:” + str + ” i=” + i + ” n=” + n);
++i;
++n;
}

public static int print(String str) {
System.out.println((++k) + “:” + str + ” i=” + i + ” n=” + n);
++n;
return ++i;
}

public static void main(String args[]) {
Test t = new Test(“init”);
}

}

这里的输出结果为:

1:j i=0 n=0
2:构造块 i=1 n=1
3:t1 i=2 n=2
4:j i=3 n=3
5:构造块 i=4 n=4
6:t2 i=5 n=5
7:i i=6 n=6
8:静态块 i=7 n=99
9:j i=8 n=100
10:构造块 i=9 n=101
11:init i=10 n=102


以下为详细分析:

  1. 首先类被加载,类中所有的静态域被初始化为0、false 或 null(注意这里并没有执行初始化语句,千万要搞明白初始化语句这里的区别)。

    变量状态:k, i, n = 0; t1, t2 = null(如n 被标志为final则n=99,且不得再次更改)

  2. 然后依照定义次序执行类中的静态域初始化语句和静态初始化块

  3. 执行到静态初始化语句 public static Test t1 = new Test(“t1”); 时,调用构造器(这里类不会再次加载,t1下面的静态初始化语句和静态初始化块并没有执行),这是会产生一个新对象 t1,对新对象不再进行类加载,而是直接执行规则2。

  4. 对象 t1 初始化输出为:

1:j i=0 n=0
2:构造块 i=1 n=1
3:t1 i=2 n=2
5. 对象 t1 构造完毕后,接下来构造 t2,过程和上面相同,这一步骤的输出为:

4:j i=3 n=3
5:构造块 i=4 n=4
6:t2 i=5 n=5
6. 然后执行 public static int i = print(“i”); 和静态初始化块,输出:

7:i i=6 n=6
8:静态块 i=7 n=99
7. 至此,类加载完毕,接下来便是 main 函数中的对象 t 的构造,构造过程为步骤 1。输出为:

9:j i=8 n=100
10:构造块 i=9 n=101
11:init i=10 n=102

原文地址:https://www.cnblogs.com/lllini/p/11955302.html