Java 说int-enum模式是编译时常量是什么意思?

Java 说int-enum模式是编译时常量是什么意思?,java,enums,effective-java,compile-time-constant,Java,Enums,Effective Java,Compile Time Constant,这是来自有效的Java 使用int-enum模式的程序是脆弱的。因为int枚举是 编译时常量,它们被编译到使用它们的客户端 有人能解释为什么int enum模式被称为compiled type constant,以及编译到客户机中的是什么意思吗 下面是这样一个常数的示例: public static final int APPLE_FUJI = 0; 值“0”本身将在编译期间内置到.class文件中。如果随后更改该值,则必须重新编译使用该值的所有内容,包括使用应用程序/库的任何客户端代码 如果

这是来自有效的Java

使用int-enum模式的程序是脆弱的。因为int枚举是 编译时常量,它们被编译到使用它们的客户端

有人能解释为什么int enum模式被称为compiled type constant,以及编译到客户机中的是什么意思吗

下面是这样一个常数的示例:

public static final int APPLE_FUJI = 0;

值“0”本身将在编译期间内置到
.class
文件中。如果随后更改该值,则必须重新编译使用该值的所有内容,包括使用应用程序/库的任何客户端代码

如果你不这样做,你将不会得到警告,而是错误的行为


如果编译时常量只在代码中使用,那么假设一个完整的清理/构建周期,问题就不会那么严重了。如果您的代码能够接触到更广泛的受众,那么这将成为一个更大的问题

假设您有两个文件:

Foo.java:
public class Foo
{
    public static final int SOMETHING = 1;
}

Bar.java:
public class Bar
{
    public static void main(String[] args)
    {
        System.out.println(Foo.SOMETHING);
    }
}
编译它们,运行
javabar
,它将打印出1

现在更改Foo.java,使
SOMETHING
为2,然后重新编译Foo.java。重新运行
java-Bar
,它仍然会打印1。常量值将被复制到使用它的每一段代码中,而不是在执行时从
Foo
请求值


在实践中,如果您在任何事情发生变化时重新编译所有内容,这不是问题。

这是Java C中为数不多的优化之一,一般来说,我宁愿它没有这样做;)Java不是一种动态绑定语言吗?我们为什么要重新编译所有东西?@Geek你不必这么做。但强烈建议这样做是为了避免Jon Skeet在上面所描述的情况。在我看来,Java编译器的这种行为是不好的。该常量应仅存储在
Foo.class
Bar
应始终从
Foo
获取该常数。就像语言中的许多其他半愚蠢的事情一样:它不会被更改,因为它可能会破坏现有的代码。真是一群哭哭啼啼的孩子…@极客:你必须定义“动态绑定语言”,让我来回答你的第一个问题。但在这种情况下,您必须重新编译的原因是,语言规范显式调用了如下常量表达式。@Jon dynamic binding,即Foo的客户端应在运行时向Foo请求属于Foo的任何常量(即动态)。类型(类)是动态绑定的,但正如前面所述,常量不是。这是一个优化。如果要保留动态类型,请使用实枚举而不是int常量。