我有一个这样的测试代码:
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
因此,类 Constants 被 JVM 加载。 但是如果我在常量类的静态字段中添加一个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遇到这段代码时会做什么(字节码)?
类或接口类型 T 将在 第一次出现以下任一情况:
- [...]
- 使用了 T 声明的静态字段,并且该字段不是常量变量(第 4.12.4 节)。
A 常量 定义为
常量变量是
原始类型或类型的变量final
使用常量表达式初始化 (§15.28)。String
所以你的字段是一个常量变量,访问它不会导致类型被初始化。
此行为是否取决于特定的 JVM?或者这是Java中的规则 语言规范?
Java 语言规范指定了此行为。
这样做的优点和缺点是什么?
缺点是可能会造成混乱(如果您不了解 Java 语言规范的详细信息)。
优点是引用常量不会导致任何不必要的代码执行。