未调用静态块

2022-09-01 09:45:37

谁能解释发生了什么?

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;
    
        
}

安慰:

最后

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

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

安慰:

类已装入

最后

注意:我已经更改了字段:并在控制台中显示它。我得到了与字符串中相同的情况。为什么?ipublic static final int i = 3;


答案 1

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

作为旁注,请注意类加载和类初始化之间的区别:只有后者的发生是由JLS精确指定的。类加载可能随时发生。


答案 2

这是在 Java 语言规范 {8.3.2.1 类变量的初始值设定项} 中编写的。这必须回答您的问题

此处的一个微妙之处是,在运行时,首先初始化最终的静态变量以及使用编译时常量值初始化的静态变量。这也适用于接口中的此类字段 (§9.3.1)。这些变量是“常量”,即使通过狡猾的程序,也永远不会观察到它们具有默认的初始值(§4.12.5)。有关更多讨论,请参阅 §12.4.2 和 §13.4.9。


推荐