类加载,静态块

时间:2019-07-16 13:56:22

标签: java static classloader

我有这段代码,我正在使用-verbose:class选项运行它,以查看已加载的类。令我惊讶的是,它显示它已加载类A1和A2,但未调用静态块。

有人可以解释这种行为吗

package P1;



import java.lang.reflect.InvocationTargetException;

public class DemoReflection {

    static {
        System.out.println("Loading Demo");
    }

    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException,
            InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        System.out.println("A2 " + A2.class.getClassLoader().getClass());
        System.out.println("Demo " + DemoReflection.class.getClassLoader().getClass());
        System.out.println("A1 " + A1.class.getClassLoader().getClass());
    }

}

class A1 {
    static {
        System.out.println("Loading A1");
    }
}

class A2 extends A1 {

    static {
        System.out.println("Loading A2");
    }

    public A2() {
        System.out.println("m2");
    }

    public void m1() {
        System.out.println("m1");
    }
}

class A3 {

    static int a3Id = 3;

    static {
        System.out.println("Loading A3");
    }

}

输出:enter image description here

2 个答案:

答案 0 :(得分:3)

JLS §8.7说:

  

在初始化类时,将执行在类中声明的静态初始化程序(第12.4.2节)。

那么初始化是什么意思?让我们参考JLS §12.4.2。这描述了详细的初始化过程。但是,这里的点JLS §12.4.1可能更合适。它说:

类或接口类型T将在以下任何一种首次出现之前立即初始化:
  • T是一个类,并创建T的实例。
  • T是一个类,并调用T声明的静态方法。
  • 分配了由T声明的静态字段。
  • 使用T声明的静态字段,并且该字段不是常量变量(第4.12.4节)。
  • T是顶级类(第7.6节),并执行一个词法嵌套在T(第8.1.3节)中的assert语句(第14.10节)。
  • 这些选项都不适合您的情况,因此不会调用静态块。

    答案 1 :(得分:0)

    简单版本: 静态块仅在您第一次创建对象或访问该类的静态成员时运行。