静态块未被调用

时间:2013-09-24 10:32:03

标签: 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;


}

控制台:

  

最终

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

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

控制台:

  

类已加载

     

最终

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

2 个答案:

答案 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。