刚换了下家,没想到刚工作了一周就有一个测试,真是触不及防。通过做题让我看到了基础的不足。特在此将此题做一记录。
题面是:一个父类有一个静态代码块、一个构造代码块、一个构造函数,然后就是一个子类继承这个父类,也包含这三个方法,请写出他们的执行顺序。
下面先用代码演示一下:
public class Father {
static {
System.out.println("the father static");
name = "in father static name";
}
public static String name = "father";
{
System.out.println("the father blocks");
}
public Father(){
System.out.println("the father constructor");
}
}
public class Son extends Father {
public static String name = "son";
static {
System.out.println("the son static");
name = "in son static name and before";
}
{
System.out.println("the son blocks");
}
public Son(){
System.out.println("the son constructor");
}
public static void main(String[] args) {
}
}
这是的运行结果:
the father static
the son static
静态代码块会优先于对象的创建,且只能加载一次,优先于主函数,用于给类初始化。main运行后进入栈内,加载Father.class进入内存,同时也将父类的静态代码块也加载进内存,然后Son.class加载进入内存,同时子类的静态代码块也加载到内存,最后结束运行。
在进行一下拓展:
那么下面的代码
public static void main(String[] args) {
Father f = new Father();
}
执行结果:
the father static
the son static
the father blocks
the father constructor
public static void main(String[] args) {
Son son = new Son();
}
执行结果:
the father static
the son static
the father blocks
the father constructor
the son blocks
the son constructor
如果在new Son();之前写一个输出语句,
public static void main(String[] args) {
System.out.println("main");
Son son = new Son();
}
此时输出结果为:the father static
the son static
main
the father blocks
the father constructor
the son blocks
the son constructor
public static void main(String[] args) {
Son son = new Son();
Son son2 = new Son();
}
执行结果:
the father static
the son static
the father blocks
the father constructor
the son blocks
the son constructor
the father blocks
the father constructor
the son blocks
the son constructor
public static void main(String[] args) {
System.out.println(Father.name);
}
执行结果:
the father static
the son static
father
public static void main(String[] args) {
System.out.println(Son.name);
}
执行结果:
the father static
the son static
in son static name and before
请注意父类和子类的静态代码块和静态变量书写顺序是相反的。由结果可以看出,静态代码块和静态变量是由书写的顺序加载的。
总结:按照静态块(静态变量)、成员变量、构造方法、静态方法(被调用时执行)依次执行。当new Son()开始执行的时候,会先去执行父类中的静态代码块,然后再执行子类中的静态代码块,当所有的静态代码块都执行结束后,会继续执行main函数中语句(按出现顺序执行),然后会去执行父类中的非静态代码块,接着是父类中的构造方法,紧接着执行子类中的非静态代码块,最后是子类中的构造方法。
补充课外知识:System.out.println(3.0/0);输出结果是Infinity,表示无穷大。