demo1-赋值
public class TestClassLoader {
public static TestClassLoader classLoader = new TestClassLoader();
public static int a;
public static int b = 0;
public static final int c = 2;
public static int d = 5;
public TestClassLoader() {
a++;
b++;
d++;
System.out.println("instance. a=" + a + ",b=" + b + ",c=" + c + ",d=" + d);
}
static {
System.out.println("static. a=" + a + ",b=" + b + ",c=" + c + ",d=" + d);
a++;
b++;
d = 2;
}
public static void main(String[] args) {
System.out.println("main. a=" + a + ",b=" + b + ",c=" + c + ",d=" + d);
}
}
demo1结果
instance. a=1,b=1,c=2,d=1
static. a=1,b=0,c=2,d=5
main. a=2,b=1,c=2,d=2
demo1结果分析
- 准备阶段,classLoader是null,a、b、d被初始化0值,c因为被final修饰,所以被初始化并赋值2
- 初始化阶段有好几步(先执行构造,再赋初始值)
先初始化classLoader执行构造函数,a,b,d都被加1,所以instance日志,a=1,b=1,c=2,d=1
之后给b赋值0,d赋值5,所以static日志,a=1,b=0,c=2,d=5 - 执行完静态代码块,a被加1,b被加1,d被赋值成2,所以最后main日志,a=2,b=1,c=2,d=2
demo2-执行顺序
public class TestClassLoader2 {
public static void main(String[] args) {
B b = new B();
}
}
class A {
static {
System.out.println("父类A静态代码块");
}
{
System.out.println("父类A非静态代码块");
}
public A() {
System.out.println("父类A构造方法");
}
}
class B extends A {
static {
System.out.println("子类B静态代码块");
}
{
System.out.println("子类B非静态代码块");
}
public B() {
System.out.println("子类B构造方法");
}
}
demo2结果
父类A静态代码块
子类B静态代码块
父类A非静态代码块
父类A构造方法
子类B非静态代码块
子类B构造方法
demo2结果分析
初始化子类(父类会被先初始化)
静态代码块内容先执行,接着执行父类非静态代码块和构造方法,然后执行子类构造代码块和构造方法。