一尘不染

Java中的静态/实例初始化程序块以什么顺序运行?

java

假设一个项目包含几个类,每个类都有一个静态初始化程序块。这些块以什么顺序运行?我知道在一个类中,这样的块按照它们在代码中出现的顺序运行。我读过所有类都一样,但是我编写的一些示例代码对此表示不同。我使用以下代码:

package pkg;

public class LoadTest {
    public static void main(String[] args) {
        System.out.println("START");
        new Child();
        System.out.println("END");
    }
}

class Parent extends Grandparent {
    // Instance init block
    {
        System.out.println("instance - parent");
    }

    // Constructor
    public Parent() {
        System.out.println("constructor - parent");
    }

    // Static init block
    static {
        System.out.println("static - parent");
    }
}

class Grandparent {
    // Static init block
    static {
        System.out.println("static - grandparent");
    }

    // Instance init block
    {
        System.out.println("instance - grandparent");
    }

    // Constructor
    public Grandparent() {
        System.out.println("constructor - grandparent");
    }
}

class Child extends Parent {
    // Constructor
    public Child() {
        System.out.println("constructor - child");
    }

    // Static init block
    static {
        System.out.println("static - child");
    }

    // Instance init block
    {
        System.out.println("instance - child");
    }
}

并得到以下输出:

  • START
  • static - grandparent
  • static - parent
  • static - child
  • instance - grandparent
  • constructor - grandparent
  • instance - parent
  • constructor - parent
  • instance - child
  • constructor - child
  • END

显而易见的答案是,父母的积木先于孩子的积木,但这只是一个巧合,如果两个班级不在同一等级中,这无济于事。

编辑:

我通过将其附加到LoadTest.java来修改了示例代码:

class IAmAClassThatIsNeverUsed {
    // Constructor
    public IAmAClassThatIsNeverUsed() {
        System.out.println("constructor - IAACTINU");
    }

    // Instance init block
    {
        System.out.println("instance - IAACTINU");
    }

    // Static init block
    static {
        System.out.println("static - IAACTINU");
    }
}

正如类名所暗示的那样,我从未在任何地方引用新类。新程序产生的输出与旧程序相同。


阅读 279

收藏
2020-03-06

共1个答案

一尘不染

类的静态初始值设定项在首次访问该类时运行,以创建实例或访问静态方法或字段。 因此,对于多个类,这完全取决于运行以加载这些类的代码。

2020-03-06