静态块未被调用

idm*_*iev 32 java final

谁能解释发生了什么?

public class MagicFinal {

    public static void main(String[] args) {
        System.out.println(A.s);
    }
}

class A {
    static {
        System.out.println("class has been loaded");
    }

    public static final String s = "final";

    public static final Integer i = 3;


}
Run Code Online (Sandbox Code Playgroud)

安慰 :

最后

那是什么?我不明白为什么没有加载类,我知道类总是在第一次调用时加载.字段s在字符串池中,我看到最终修饰符是魔术.

如果我删除final修饰符(public static String s = "final"),我会得到

安慰 :

类已加载

最后

注意:我更改了字段i:public static final int i = 3;并在控制台中显示它.我和String情况一样.为什么?

Mar*_*nik 46

"final"是一个字符串文字,因此是一个编译时常量表达式.static final使用编译时常量表达式初始化的变量的值直接硬编码到引用它的类中,并且不引用原始类.因此,不会发生原始类的初始化.

作为一个侧面,请注意类加载和类初始化之间的区别:只有后者的出现由JLS精确指定.类加载可以随时发生.

  • 请阅读我在答案中链接的编译时常量表达式的定义.`int`是一个原始值,`String`是引用类型值的唯一特例,它可以包含在常量表达式中,而`Integer`则不是. (4认同)
  • @ X86如果`"类已加载"`不打印,则该类尚未初始化.根据JLS,类总是懒惰地初始化.根据JVM运行时的决定,A类可以在任何时候获得*加载*或根本不加载*.请注意,类加载不应该导致任何可观察到的影响. (2认同)