java - 为什么这个枚举代码是对静态字段的非法引用?

标签 java enums

此代码无法编译,因为存在对静态字段的非法引用。

public enum Foo {

  A,
  B;

  private Foo[] foos = new Foo[] { Foo.A };

}

你不应该能够从非静态字段初始化器访问静态字段吗?例如:

public class Foo {

  static int A;

  private int[] foos = new int[] { Foo.A };

}

这编译得很好。

请注意,在第一个示例中将 foos 设置为静态编译。

最佳答案

查看 Java 语言规范,第三版,第 8.9 节 http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.9

It is a compile-time error to reference a static field of an enum type that is not a compile-time constant (§15.28) from constructors, instance initializer blocks, or instance variable initializer expressions of that type. It is a compile-time error for the constructors, instance initializer blocks, or instance variable initializer expressions of an enum constant e to refer to itself or to an enum constant of the same type that is declared to the right of e.

讨论

Without this rule, apparently reasonable code would fail at run time due to the initialization circularity inherent in enum types. (A circularity exists in any class with a "self-typed" static field.) Here is an example of the sort of code that would fail:

enum Color {
        RED, GREEN, BLUE;
        static final Map<String,Color> colorMap = 
        new HashMap<String,Color>();
        Color() {
            colorMap.put(toString(), this);
        }
    } 

Static initialization of this enum type would throw a NullPointerException because the static variable colorMap is uninitialized when the constructors for the enum constants run. The restriction above ensures that such code won't compile.

关于java - 为什么这个枚举代码是对静态字段的非法引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9098862/

相关文章:

java - (Node.js、socket.io)JSONObject 无法转换为 int

java - 命名枚举类型

postgresql - 在 PostgreSQL 中插入多个 ENUM 值

java - java.util.EnumSet<E> 是如何工作的?

java - 使用 apache Camel 将文件类型从 csv 转换为 xml

java - 将值移至 JTextField

java - 从java中的方法更改数组的大小

java - 使用多个事务管理器时没有 Hibernate session 绑定(bind)到线程

Java和从int获取枚举的方法的命名

c# - Entity Framework Search for Enum 拉回所有数据