为什么引用静态final字段不会触发类加载?

时间:2014-03-26 02:37:28

标签: java compiler-construction jvm

我有一个像这样的测试代码:

public class Constants {
public static String c1 = "C1";

static {
    System.out.println("Constants Class Loaded!");
}
}

public class Test {
    public static void main(String[] args) {
        String c1 = Constants.c1;
        System.out.println(c1);
    }
}

它的输出是:

Constants Class Loaded!
C1

因此,类常量由JVM加载。 但是如果我在类Constants中的静态字段中添加一个final关键字:

public class Constants {
public static final String c1 = "C1";

static {
    System.out.println("Constants Class Loaded!");
}
}

其输出更改为:

C1

似乎没有加载类Constants。

我的当地环境是:

OS: Win7 x64
JVM: JRockit (build R28.2.0-79-146777-1.6.0_29-20111005-1808-windows-ia32, compiled mode)

所以,我的问题是:

  • 为什么引用静态final字段不会触发类加载?当JVM满足此代码时,它会做什么(字节码)?
  • 此行为是否取决于特定的JVM?或者这是Java语言规范中的规则?
  • 优点和优点是什么?这个缺点?

感谢。

1 个答案:

答案 0 :(得分:4)

  

为什么引用静态final字段不会触发类加载?   JVM在满足此代码时会做什么(字节码)?

The JLS says

  

类或接口类型T将在紧接之前初始化   首次出现以下任何一种情况:

     
      
  • [...]
  •   
  • 使用由T声明的静态字段,该字段不是常量变量(§4.12.4)。
  •   

constant variable定义为

  

常量变量是基本类型或类型的final变量   String用常量表达式初始化(​​§15.28)。

因此,您的字段是一个常量变量,访问它不会导致类型被初始化。

  

此行为是否取决于特定的JVM?或者这是Java中的规则   语言规范?

Java语言规范指定了这种行为。

  

有什么好处&这个缺点呢?

缺点是可能导致混淆(如果您不了解Java语言规范的详细信息)。

优点是引用常量不会导致任何不必要的代码执行。