Java类加载的顺序
类加载优于类实例化对象
类加载:程序从上到下,加载静态的初始化语句,初始化块和构造方法
类创建对象:程序从上到下,加载非静态的初始化语句,初始化块和构造方法
类初始化变量初始值
类初始化变量的默认值如下:
byte、short、int :0
long :0L
float :0.0f
double :0.0d
char :空字符(即:/u0000)
boolean :false
引用类型 :null
代码示例
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;
{
print("构造块");
j=100;
}
public InitializeDemo(String str) {
System.out.println((k++) + ":" + str + " i=" + i + " n=" + n);
++i;
++n;
}
static {
print("静态块");
n=100;
}
private int j = print("j");
public static int print(String str) {
System.out.println((k++) + ":" + str + " i=" + i + " n=" + n);
++n;
return ++i;
}
public static void main(String[] args) {
System.out.println("123");
InitializeDemo n =new InitializeDemo("初始化");
}
}
执行顺序分析
程序运行开始,需要寻找程序的入口(Main方法),在这里,由于main方法是在InitializeDemo 类内部的,因此需要先加载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;
在执行第二句话的时候会暂停类加载,转而执行实例化类对象
(从上到下,执行非静态的初始化语句)
{
print("构造块");
j=100;
}
private int j = print("j");
public InitializeDemo(String str) {
System.out.println((k++) + ":" + str + " i=" + i + " n=" + n);
++i;
++n;
}
在这里就调用了print()方法;
由于指定t1,t2时 i,n还没有赋值,仍然是默认值0,所以输出的值需要仔细考虑
实际上只有执行完那五行静态初始化语句才会给i,n赋值;也就是只有main方法内的new 对象才能享用这个赋值完毕的i,n
注意:main方法是程序入口,如果main方法不在这个类中,那么不会先加载这个InitializeDemo类,而是会先调用
System.out.println("123");
然后在
InitializeDemo n =new InitializeDemo("初始化");
new 之前加载InitializeDemo类,然后再去new InitializeDemo()
最后贴上执行结果,供大家思考
1:构造块 i=0 n=0
2:j i=1 n=1
3:t1 i=2 n=2
4:构造块 i=3 n=3
5:j i=4 n=4
6:t2 i=5 n=5
7:i i=6 n=6
8:静态块 i=7 n=99
123
9:构造块 i=8 n=100
10:j i=9 n=101
11:初始化 i=10 n=102
Process finished with exit code 0