谁能解释发生了什么?
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"
),我会得到
控制台:
类已加载
最终
注意:我更改了字段i
:public static final int i = 3;
并在控制台中显示它。
我和String情况一样。为什么呢?
答案 0 :(得分:46)
"final"
是字符串文字,因此是compile-time constant expression。使用编译时常量表达式初始化的static final
变量的值直接硬编码到引用它的类中,并且不引用原始类。因此,不会发生原始类的初始化。
作为一个侧面,请注意类加载和类初始化之间的区别:只有后者的出现由JLS精确指定。类加载可以随时发生。
答案 1 :(得分:3)
这是用Java语言规范{8.3.2.1类变量的初始化器}编写的。这必须回答你的问题
这里的一个微妙之处在于,在运行时,最终的静态变量和那些 初始化的编译时常量值首先被初始化。这也是 适用于接口中的此类字段(第9.3.1节)。这些变量是“常数” 永远不会被观察到具有默认的初始值(§4.12.5),即使是狡猾的 程式。有关更多讨论,请参见§12.4.2和§13.4.9。