看本章之前可以先去看博主的另外一篇博客:面试tips----java--关于static定义初始化块和静态变量以及初始化块的执行顺序问题(1)_static块中初始化的变量-CSDN博客

版本一:main 在子类 Child

class Parent {
    static {
        System.out.println("父类静态代码块");
    }
    {
        System.out.println("父类实例代码块");
    }
    public Parent() {
        System.out.println("父类构造方法");
    }
    public static void staticMethod() {
        System.out.println("父类 static 方法");
    }
}

class Child extends Parent {
    static {
        System.out.println("子类静态代码块");
    }
    {
        System.out.println("子类实例代码块");
    }
    public Child() {
        System.out.println("子类构造方法");
    }
    public static void staticMethod() {
        System.out.println("子类 static 方法");
    }

    public static void main(String[] args) {
        System.out.println("== new Parent() ==");
        Parent p = new Parent();

        System.out.println("== new Child() ==");
        Child c = new Child();

        System.out.println("== 调用静态方法 ==");
        Child.staticMethod();
    }
}

输出结果:

父类静态代码块
子类静态代码块
== new Parent() ==
父类实例代码块
父类构造方法
== new Child() ==
父类实例代码块
父类构造方法
子类实例代码块
子类构造方法
== 调用静态方法 ==
子类 static 方法

📌 分析:

  • 程序启动先加载 Child(因为 main 在里面),于是先执行:

    • 父类静态代码块 → 子类静态代码块

  • new Parent():只触发父类实例部分。

  • new Child():父类实例块 + 父类构造方法 → 子类实例块 + 子类构造方法。

  • 调用 Child.staticMethod():只执行子类的静态方法。


版本二:main 在独立的 Test

class Parent {
    static {
        System.out.println("父类静态代码块");
    }
    {
        System.out.println("父类实例代码块");
    }
    public Parent() {
        System.out.println("父类构造方法");
    }
    public static void staticMethod() {
        System.out.println("父类 static 方法");
    }
}

class Child extends Parent {
    static {
        System.out.println("子类静态代码块");
    }
    {
        System.out.println("子类实例代码块");
    }
    public Child() {
        System.out.println("子类构造方法");
    }
    public static void staticMethod() {
        System.out.println("子类 static 方法");
    }
}

public class Test {
    public static void main(String[] args) {
        System.out.println("== new Parent() ==");
        Parent p = new Parent();

        System.out.println("== new Child() ==");
        Child c = new Child();

        System.out.println("== 调用静态方法 ==");
        Child.staticMethod();
    }
}

输出结果:

== new Parent() ==
父类静态代码块
父类实例代码块
父类构造方法
== new Child() ==
子类静态代码块
父类实例代码块
父类构造方法
子类实例代码块
子类构造方法
== 调用静态方法 ==
子类 static 方法

📌 分析:

  • 程序启动先加载 Test,不会立刻加载 Parent / Child

  • new Parent() → 才加载 Parent(父类静态块先执行),然后实例化父类。

  • new Child() → 再加载 Child(子类静态块执行一次),然后实例化父子类。

  • 静态方法同理,只执行方法,不创建对象。


🌟 笔记总结

  1. 加载顺序

    • 父类静态块 → 子类静态块(只执行一次,类加载时执行)

    • 父类实例块 → 父类构造方法

    • 子类实例块 → 子类构造方法

  2. 不同点

    • mainChild:启动时就加载 ChildParent,所以静态块最早执行。

    • mainTest:只加载 Test,等用到 Parent/Child 时才加载,所以静态块延迟执行。

  3. 静态方法

    • 属于类级别,不会触发对象创建。

    • 如果类未加载,会先触发类加载(从而执行静态块)。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐