先上代码
public class Test {
public static void main(String args[]){
System.out.println("main方法");
b();
}
static Test tee = new Test();
static int b2 = 8;
static {
System.out.println("静态代码块");
}
Test(){
System.out.println("Test的构造函数");
System.out.println("a="+a+"b="+b2);
}
{System.out.println("非静态代码块");}
public static void b(){
System.out.println("b静态方法");
}
int a = 110;
}
运行main方法的输出结果如下:
非静态代码块
Test的构造函数
a=110b=0
静态代码块
main方法
b静态方法
结果有点出乎意料,两个疑惑:
一是非静态代码块竟然比静态代码块先执行,
二是b的值竟然是0。。
其实,仍然是最先执行静态代码的,只不过按编写的顺序来执行。
仔细看下代码,第一个static是new Test() 对象。既然是new 对象,那么就该执行非静态代码块、初始化实例变量 a、执行构造函数 ,所以就会先输出了
非静态代码块
Test的构造函数
a=110b=0
那么为什么静态变量b2的值是0呢?原因是还没有执行到 static int b2 = 8; 这个语句,所以静态变量b2是默认值0。
如果,把 static int b2 = 8; 放在 static Test tee = new Test(); 语句之前,那么在new Test()之前就已经给b2赋值了(赋值为8),此时的输出结果就是
非静态代码块
Test的构造函数
a=110b=8
静态代码块
main方法
b静态方法
再来个转折,如果b2是final (常量)类型的,即 static final int b2 = 8;
那么无论该语句放在哪行,输出结果都是 b=8,即已经给b2赋指定值。。
这是因为static final变量在类初始化前的准备阶段,就已经给该变量赋指定值。。
如果只是static变量,在该阶段只会赋默认值(0)。。
更多可参考文章:java类加载流程 https://mp.weixin.qq.com/s/pU-yPiO2F5lBcaxcV0lS5g
后记:
通用代码执行顺序:
1.父类静态代码
2.子类静态代码
3.父类非静态代码
4.父类构造方法
5.子类非静态代码
6.子类构造函数
main方法在被执行前,会先执行main方法所在类的静态代码。