Java的静态变量,成员变量,静态代码块,构造快的加载顺序
今天在看静态代码块执行顺序相关文章时遇到一个挺有意思的题目,题目如下:
public class StaticTest{
static StaticTest st = new StaticTest();
public static void staticFunction(){
System.out.println("4");
}
static{
System.out.println("1");
}
StaticTest(){
System.out.println("3");
System.out.println("a="+a+" b="+b);
}
int a=100;
static int b=112;
{
System.out.println("2");
}
public static void main(String args[]){
staticFunction();
}
}
猜一下执行后在控制台打印的结果,刚开始看到后认为顺序应该是这样的:
1
2
3
a=100 b=112
4
但是实际上运行后的结果是这样的:
2
3
a=100 b=0
1
4
后来看了分析,原来过程是这样的:
类的生命周期是:加载->验证->准备->解析->初始化->使用->卸载
准备和初始化阶段涉及类变量的初始化和赋值
准备阶段:为static类变量分配内存并设置默认值,st = null b = 0
初始化阶段:
执行类构造器
先按顺序执行静态变量,static StaticTest st = new StaticTest();
然后会执行StaticTest()方法,执行前先执行构造代码块再初始化成员变量,所以先输出2,a=100,b由于已经初始化完毕,不执行
执行StaticTest()中的输出3,,a=100,b=0
StaticTest()执行完之后,顺序执行static代码块,输出1
main中调用staticfunction 输出4
所以执行代码时候打断点看到的顺序是这样的:
执行构造代码块——》初始化成员变量——》执行static变量初始化——》执行静态变量——》执行方法——》继续执行static代码块——》main调用方法;
通过这短短几行代码对类加载顺序有了更深刻的了解。