Java 中静态代码块,代码块,构造器的执行先后顺序

时间:2021-01-10 19:35:55

结论:
顺序:父类的静态代码块>子类的静态代码块>父类的代码块>父类的构造函数>子类的代码块>子类的构造函数。
分析

  1. 当new一个对象的时候,要先有类的信息吧。那就得先加载类的信息,所以会最先执行静态代码块,而要有子类的信息,就要先有父类的信息,要先加载父类的信息。也就是先执行父类的静态代码块,然后执行子类的静态带块。
  2. 然后好初始化一个对象,必须要有对象的信息吧,所以得先加载对象的信息,这事会先执行代码块,最后对象的信息加载完毕,要初始化这个对象,这时再执行构造函数。还是本着先有父类再有子类的原则,也是就是先执行父类的代码块,再执行父类的构造器,接着执行子类的代码块,执行子类的构造器。

代码块和构造器都是和对象相关的,所以每次生成一个对象代码块和构造器都会执行一次。而静态代码块是在类加载的时候执行的,类只需要加载一次就够了,所以只需要执行一次就够了**
下面是实例代码:
父类代码:

public class Person {
    //父类构造器
    public Person()
    {
        System.out.print("父类构造器执行-->");
    }
    //父类代码块:
    {
        System.out.print("父类代码块执行-->");
    }
    //父类静态代码块:
    static
    {
        System.out.print("父类静态代码块执行-->");
    }
}

子类代码:

public class Son extends Person {
    //构造器:
    public Son()
    {
        System.out.println("子类构造器执行-->");
    }
    //代码块:
    {
        System.out.print("子类代码块执行-->");
    }
    //静态代码块:
    static 
    {
        System.out.print("子类静态代码块执行-->");
    }
}

测试类:

public class Test {
    public static void main(String[] args)
    {
        Son son=new Son();
        Son son2=new Son();
    }
}

运行结果:

父类静态代码块执行-->子类静态代码块执行-->父类代码块执行-->父类构造器执行-->子类代码块执行-->子类构造器执行-->
父类代码块执行-->父类构造器执行-->子类代码块执行-->子类构造器执行-->

如果一个类中有多个静态代码块,多个代码块,则按照其在类中定义的上下循序一次执行,上面的静态代码块先执行,然后执行下面的静态代码块,代码块也是如此。
总结一下:

  1. 先执行父类先定义的静代码块,然后执行父类后定义的其他静态代码块
  2. 执行子类先定义的静态代码块,然后执行子类后定义的其他静态代码块
  3. 执行父类中先定义的普通代码块,然后执行父类中后定义的其他普通代码
  4. 按参数列表执行父类对应的构造器(如果有多个构造器的话)
  5. 然后执行子类中先定义的普通代码块,然后执行子类中后定义的其他普通代码块
  6. 最后执行子类的构造器

实例:在上面的父类和子类中分别加上普通代码块,和静态代码块即可:
父类:

public class Person {
    //父类构造器
    public Person()
    {
        System.out.print("父类构造器执行-->");
    }
    //父类代码块:
    {
        System.out.print("父类代码块1执行-->");
    }
    {
        System.out.print("父类代码块2执行-->");
    }
    //父类静态代码块:
    static
    {
        System.out.print("父类静态代码块1执行-->");
    }
    static
    {
        System.out.print("父类静态代码块2执行-->");
    }

}

子类:

public class Son extends Person {
    //构造器:
    public Son()
    {
        System.out.println("子类构造器执行-->");
    }
    //代码块:
    {
        System.out.print("子类代码块1执行-->");
    }
    {
        System.out.print("子类代码块2执行-->");
    }
    //静态代码块:
    static 
    {
        System.out.print("子类静态代码块1执行-->");
    }
    static 
    {
        System.out.print("子类静态代码块2执行-->");
    }
}

测试类还是上面的那个测试类
测试结果:

父类静态代码块1执行-->父类静态代码块2执行-->子类静态代码块1执行-->子类静态代码块2执行-->父类代码块1执行-->父类代码块2执行-->父类构造器执行-->子类代码块1执行-->子类代码块2执行-->子类构造器执行-->
父类代码块1执行-->父类代码块2执行-->父类构造器执行-->子类代码块1执行-->子类代码块2执行-->子类构造器执行-->