说int枚举模式是编译时常量是什么意思?

Gee*_*eek 13 java enums compile-time-constant effective-java

这来自Effective Java

使用int枚举模式的程序很脆弱.因为int枚举是编译时常量,所以它们被编译到使用它们的客户端中.

有人可以解释为什么int枚举模式被称为编译类型常量以及编译到客户端的含义是什么?

这是一个这样一个常数的例子:

public static final int APPLE_FUJI = 0;
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 18

假设您有两个文件:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

编译它们,运行java Bar并打印出1.

现在更改Foo.java,使其SOMETHING为2,并重新编译Foo.java.重新运行java Bar并且它仍然会打印1.常量值将被复制到使用它的每一段代码,而不是Foo在执行时询问值.

在实践中,如果您在任何时候重新编译任何内容,那么这不是问题.

  • @Geek你没有**做**.但强烈建议为了避免Jon Skeet在上面描述的内容.在我看来,Java编译器的这种行为很糟糕.该常量只应存储在`Foo.class`中.`Bar`应该总是从'Foo`得到那个常量.像语言中许多其他半愚蠢的东西一样:它不会被改变,因为它可能会破坏现有的代码.真是一堆哭泣的婴儿...... (3认同)
  • 类型(类)是动态绑定的,但如上所述,常量不是.这是一个优化.如果要保留动态类型,请使用实际枚举而不是int常量. (2认同)

Bri*_*new 6

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

如果不这样做,您将不会收到警告,而是行为不正确.

如果您的编译时常量仅用于您的代码中,那么假设完整的清理/构建周期则不会出现问题.如果您的代码随后扩大到更广泛的受众群体,那么这就变得更加困难了.