定义一个父类Test
public class Test {
static int age = 10; // 静态变量age
static {
System.out.println("Test静态代码块");
}
{
System.out.println("Test普通代码块");
}
public static void exam() {
System.out.println("Test静态方法");
}
public Test() {
System.out.println("Test无参构造方法");
}
}
定义一个子类Demo
public class Demo extends Test {
static {
System.out.println("Demo静态代码块");
}
{
System.out.println("Demo普通代码块");
}
public Demo() {
System.out.println("Demo无参构造");
}
public static void main(String[] args) {
Test.exam();
new Demo();
System.out.println(Test.age);
}
}
首先当类加载的时候,会自动加载静态代码块,静态的都是和类一起加载的。并且静态变量和静态方法是根据调用顺序来执行的。
当我们运行Demo类时,结果会是什么呢?
首先当虚拟机加载Demo类时,他会自动加载静态代码块,因为Demo继承了Test类,它会先去找Test类当中有没有静态代码块,如果有,则按顺序运行父类中的静态代码块。如果执行完或没有,则运行当前类的静态方法。故会依次输出 Test静态方法–>Demo静态方法两个结果。然后执行new Demo(); 在执行子类的实例化之前,虚拟机又会去父类找普通代码块,如果有则执行,没有则会去调用父类的构造方法。随后去调用子类的普通代码块,然后才去执行子类的构造方法。所以会依次输出:Test普通代码块–>Test无参构造方法–>Demo普通代码块–>Demo无参构造.。随后执行**System.out.println(“Test.age”);**语句,输出10。故程序的输出结果如下图所示:

总结
当加载Demo类时,JVM会去调用该类父类的静态代码块,父类的静态代码块运行完后去执行子类的静态代码块。当子类的静态代码块执行完毕后JVM又会去找父类中的普通代码块,当父类的普通代码块执行完毕后又会调用父类的构造方法。父类的构造方法执行完毕后,JVM又会去看子类中有没有普通代码块,如果有则执行。执行完毕后,会去调用子类的构造方法。这就是他们之间的顺序。
注意:java中所有类都是Object类的子类。当父类中含有有参构造而没有显示的写出无参构造,则子类必须用super关键字显示的调用父类的有参构造,否则编译将不通过。
本文围绕Java中父类Test和子类Demo展开,介绍了类加载时静态代码块的执行顺序,即先父类后子类。实例化时,先执行父类普通代码块和构造方法,再执行子类普通代码块和构造方法。还提醒若父类有有参无无参构造,子类需用super调用有参构造。

1271

被折叠的 条评论
为什么被折叠?



