内容均为网上收集整理,供自己学习做笔记用

一,原理:

  1. static初始化块是在构造函数之前执行的,而且只会执行一次,即类的首次加载时。
      初始化是在类加载的时候完成的,而构造方法是生成对象的,生成对象肯定是在类加载完成之后完成的。所以先加载,后生成(对象),故先执行初始化块。
  2. 初始化块分为静态与非静态两种,静态初始化块只会执行一次,无论new多少次,他只会执行一次。反而非静态初始化块则不是这样的,每次new他都会执行一次,执行顺序先静态再非静态。
  3. 无论是静态或者是非静态,它们的执行顺序都会在构造方法之前。
  4. 在存在父子类的情况下,在执行完非静态代码块后会立即执行其构造函数然后执行子类的非静态代码块然后执行子类的构造方法。

二,练习

class A {
    public A() {
        System.out.println("class A");
    }
    { System.out.println("I'm A class"); }
    static { System.out.println("class A static"); }
}
public class B extends A {
    public B() {
        System.out.println("class B");
    }
    { System.out.println("I'm B class"); }
    static { System.out.println("class B static"); }

    public static void main(String[] args) {
        new B();
    }
}
运行第一次结果:
class A static
class B static
I'm A class
class A
I'm B class
class B

运行第二次结果:
I'm A class
class A
I'm B class
class B
  1. 首先,static静态代码块肯定是第一步执行的,因为在类初始化的时候就会执行static代码块,构造方法肯定是最后执行,这样顺序就可以确定了。
  2. B继承A,所以先执行父类A的静态代码块,在执行B的静态代码块。
  3. 然后执行非静态的代码块,还是先执行父类A的。
  4. 此时A已经加载完毕,执行完父类的非静态代码块会紧接着执行父类的构造方法(如果有的话),此时A的静态代码块、非静态代码块、构造方法全部执行完毕,回到子类B。
  5. 子类B开始执行非静态的代码块,然后直接执行构造方法,初始化过程完毕。

补充:static修饰的语句或变量的特点有:

  1. 随着类的加载而加载
  2. 优先于对象存在
  3. 为所有的对象共享
  4. 可以使用类名调用,即类方法