直接上代码
public class InitializeDemo {
private static int k = 1;
private static InitializeDemo t1 = new InitializeDemo("t1");
private static InitializeDemo t2 = new InitializeDemo("t2");
private static int i = print("I");
private static int n = 99;
static {
print("静态块");
}
private int j = print("j");
{
print("构造块");
}
public InitializeDemo(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[]) {
new InitializeDemo("init");
}
}
这里需要理解jvm对类加载和对象加载两个流程
- 如果类中包含static字段或者静态代码块时,在类加载时会有<clinit>方法,对静态变量进行初始化,然后再执行init对象初始化。
- <clinit>执行过程中,静态变量和静态代码块执行优先级相同,执行顺序取决于书写顺序。
- <clinit>执行过程中,没有给静态变量赋值时,变量的其实是"零"值,这是在类加载的准备阶段赋予的值。
- 在对象初始化中,非静态成员变量和非静态代码块执行优先级相同,执行顺序取决于书写顺序,但是都优先于构造方法。
只说明了关键点,具体细节请看jvm类加载过程。
所以分析过程和输出结果为:
输出结果:
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
分析过程:
k=1
输出 1:j i=0 n=0
k=2
n=1
I=1
输出 2:构造块 i=1 n=1
k=3
n=2
I=2
输出 3:t1 i=2 n=2
k=4
I=3
n=3
输出 4:j i=3 n=3
k=5
I=4
n=4
输出 5:构造块 i=4 n=4
k=6
I=5
n=5
输出 6:t2 i=5 n=5
k=7
I=6
n=6
输出 7:i i=6 n=6
k=8
I=7
n=7
I=7
n=99
输出 8:静态块 i=7 n=99
k=9
I=8
n=100
输出 9:j i=8 n=100
k=10
I=9
n=101
输出 10:构造块 i=9 n=101
k=11
I=10
n=102
输出 11:init i=10 n=102
网友评论