在不看答案之前,先猜测一下答案吧!
package com.company;
class ParentClass {
public ParentClass() {
System.out.println("父类无参构造代码块 ");
}
public ParentClass(String name) {
System.out.println("父类有参构造代码块 " + name);
}
{
System.out.println("父类构造代码块 ");
}
static {
System.out.println("父类静态代码块 ");
}
}
public class SubClass extends ParentClass {
public SubClass() {
System.out.println("子类无参构造代码块 ");
}
public SubClass(String name) {
System.out.println("子类有参构造代码块 " + name);
}
{
System.out.println("子类构造代码块");
}
static {
System.out.println("子类静态代码块");
}
public static void main(String[] args) {
System.out.println("-------main start-------");
new SubClass("张三");
System.out.println("-------main end-------");
}
}
打印的结果为:
父类静态代码块
子类静态代码块
-------main start-------
父类构造代码块
父类无参构造代码块
子类构造代码块
子类有参构造代码块 张三
-------main end-------
先看main方法执行之前的过程,Java虚拟机先加载静态代码块,然后再去执行main方法。
执行静态代码块也分顺序,先加载父类,再加载子类。故为:
父类静态代码块
子类静态代码块
如果不能理解,可以这么想,静态代码块中的数据如果没有执行,万一在main方法中用到了呢?因为static的创建是需要单独分一个空间给它安置的。这么考虑的话,那static就分一个级别了,先执行普通static,再执行main方法上的static。
然后是执行main方法里面的方法。
父类构造代码块
父类无参构造代码块
子类构造代码块
子类有参构造代码块 张三
可以看到,先执行了父类构造代码块,然后再执行父类无参构造代码块,为什么呢?
看一下父类的反编译文件:
class ParentClass {
public ParentClass() {
System.out.println("父类构造代码块 ");
System.out.println("父类无参构造代码块 ");
}
public ParentClass(String name) {
System.out.println("父类构造代码块 ");
System.out.println("父类有参构造代码块 " + name);
}
static {
System.out.println("父类静态代码块 ");
}
}
发现Java虚拟机自动把父类构造代码块,分别放进了父类的无参与有参构造方法里面了,而且是放置在第一行的。故子类加载时,需先加载父类无参构造方法,解释可以看我的第一篇Java面试之父子类(1)
因此输出的结果为:
父类构造代码块
父类无参构造代码块
子类构造代码块
子类有参构造代码块 张三