考虑一下这种情况:
public Class1 {
public static final String ONE = "ABC";
public static final String TWO = "DEF";
}
public Class2 {
public void someMethod() {
System.out.println(Class1.ONE + Class1.TWO);
}
}
通常,您会期望编译器内联1和2常量。然而,这种行为是有保证的吗?您是否可以在运行时在类路径中没有Class1的情况下部署Class2,并期望它与编译器无关地工作,或者这是一个可选的编译器优化吗?
编辑:到底为什么要这样做?我有一个常量,它将在应用程序的两端(通过RMI的客户端和服务器)共享,在这种特殊情况下,将常量放在只能位于分割线一侧的类中(因为它在逻辑上拥有常量值),而不是将其放在任意常量类中,因为它需要由代码的两端共享,这将是非常方便的。在编译时,它全部是一组源文件,但在构建时,它是按包划分的。
发布于 2009-09-10 18:24:47
使用javac 1.6.0_14编译会产生以下字节码:
public void someMethod();
Code:
0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3; //String ABCDEF
5: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
因此,字符串在编译时连接在一起,结果被包含在class2的常量池中。
发布于 2009-09-10 18:13:09
参见JLS 13.4.9。虽然它没有显式地要求编译器内联常量,但它暗示条件编译和对switch
语句中常量的支持会导致编译器始终内联常量。
发布于 2009-09-10 19:08:11
看起来您正在编写内置于enum
中的功能的您自己的版本,它为您执行public static final
,通过name()
和toString()
进行正确的命名(以及其他一些优点,但可能具有较大内存占用的缺点)。
您使用的是不包含枚举的旧版本Java吗?
https://stackoverflow.com/questions/1406616
复制相似问题