Java代码执行顺序-顺口溜

1,743 阅读3分钟

代码执行顺序虽然是很基础的东西,但是还是有很多人搞不清楚其中的细节。 关于java代码的执行顺序,我编了一段顺口溜,相信你再也不会被这个问题难住了。

这段顺口溜是这样的:

  • 子类加载父类快,
  • 加载初始化静态,
  • 静态成员静态块,
  • 对象构造父类快,
  • 对象成员公共块,
  • 最后执行构造块。 这就是代码的执行顺序,其实很简单,下面详细解释。

Java代码执行顺序

类加载阶段

相信你对类加载阶段已经足够了解了,如果还不够了解,建议你阅读我的 你不知道的虚拟机类加载机制。 然后来理解这个顺口溜的前三句。

  • 子类加载父类快 也就是在加载子类的时候必须先加载父类。

  • 加载初始化静态 静态成员和静态代码块是类的元数据信息,在类初始化的时候执行。

  • 静态成员代码块 静态成员的初始化后,静态代码块执行。

程序运行阶段

现在来理解这个顺口溜的后三句。 这是在类加载阶段完成,程序运行的阶段执行的。

  • 对象构造父类快 这句话是说new一个对象的时候一定要是parent先构造,这里你或许会有点疑问:“平时继承类的时候也没调用super函数呀?”,这是因为如果parent有默认的构造函数,那子类也不需要显示调用。否则是必须要这么做的。
  • 对象成员公共块 对象初始化的过程先执行对象成员的初始化、然后是公共代码块的执行。

公共代码块是所有重载的构造函数的公共部分,是指类似这样的一段代码:

{
    System.out.println("构造代码块 " );
}
  • 最后执行构造块 对象的成员和代码块都执行完之后,才是构造函数。如果有parent,那按照parent成员、parent代码块、parent构造函数之后,再child依次执行的顺序来执行。

具体例子

建议运行下面的例子,来理解这段顺口溜。

public class Parent {
    static int staticV;
    static {
        System.out.println("staticV = " + staticV);
        System.out.println("parent 静态代码块  " );

    }
    int v;
    {
        System.out.println("v = " + v);
    }
    {
        System.out.println(" parent 构造代码块 " );
    }

    public Parent(int v) {
        this.v = v;
        System.out.println(" parent 构造函数 "  +v);
    }
}
public class Child extends Parent{


    static int staticV;
    static {
        System.out.println("staticV = " + staticV);
        System.out.println("child 静态代码块  " );

    }
    int v;
    {
        System.out.println("v = " + v);
    }
    {
        System.out.println(" child 构造代码块 " );
    }

    public Child() {
        super(1);
        System.out.println(" child 构造函数 " );
    }


    public static void main(String[] args) {
        Child child = new Child();
    }

}

运行将返回:

staticV = 0
parent 静态代码块  
staticV = 0
child 静态代码块  
v = 0
 parent 构造代码块 
 parent 构造函数 1
v = 0
 child 构造代码块 
 child 构造函数 

注意事项

就像上面提到的那样,parent如果没有默认的无参构造函数,那就必须在子类里面显示的调用父类的构造函数,否则会导致程序编译不通过。