Java 枚举静态最终实例变量
好哇!
这段代码工作了一段时间,然后我决定添加默认颜色,然后它停止工作。我收到以下错误:
1 error found:
File: Status.java [line: 20]
Error: Status.java:20: illegal reference to static field from initializer
在编译时使用以下代码。
import java.awt.Color;
enum Status
{
OFF ("Off"),
TRAINING ("Training", new Color(255, 191, 128)),
BEGINNER ("Beginner", new Color(128, 255, 138)),
INTERMEDIATE ("Intermediate", new Color(128, 212, 255)),
ADVANCED ("Advanced", new Color(255, 128, 128));
public final String name;
public final Color color;
public static final Color defaultColor = Color.WHITE;
Status(String name)
{
this(name, defaultColor);
}
Status(String name, Color color)
{
this.name = name;
this.color = color;
}
}
据我所知,这应该可行,但无论出于何种原因,Java 决定抛出一个错误。 有什么想法吗?
Huzzah!
This code worked for a time, then I decided to add a default color, and it stopped working. I get the following error:
1 error found:
File: Status.java [line: 20]
Error: Status.java:20: illegal reference to static field from initializer
With the following code at compile-time.
import java.awt.Color;
enum Status
{
OFF ("Off"),
TRAINING ("Training", new Color(255, 191, 128)),
BEGINNER ("Beginner", new Color(128, 255, 138)),
INTERMEDIATE ("Intermediate", new Color(128, 212, 255)),
ADVANCED ("Advanced", new Color(255, 128, 128));
public final String name;
public final Color color;
public static final Color defaultColor = Color.WHITE;
Status(String name)
{
this(name, defaultColor);
}
Status(String name, Color color)
{
this.name = name;
this.color = color;
}
}
This should work, as far as I can tell, but for whatever reason Java decided to throw an error.
Any thoughts?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
defaultColor
仅在调用构造函数之后才会被初始化 - 因此在此之前它将具有默认值 (null)。一种选择是将默认颜色放入嵌套类型中:当然,如果您仅在代码中引用默认颜色一次,您也可以在构造函数中对其进行硬编码称呼:
defaultColor
will only be initialized after the constructors have been called - so it will have its default value (null) until that time. One option would be to put the default colour in a nested type:Of course, if you're only referring to the default colour once in the code, you might as well hard-code it within the constructor call:
必须首先初始化枚举常量。要初始化它们,必须调用构造函数。第一个构造函数引用一个静态字段,该字段在调用时不可能已初始化。
The enum constants have to be initialized first. To initialize them, the constructors must be called. The first constructor references a static field that could not possibly have been initialized at the time it is called.
Java允许这样做
,当然在运行时会出现问题,但Java不在乎。安排 init 序列是程序员的工作,编译器检查所有损坏的 init 依赖项并不容易。无论如何,这个问题很容易解决:
但对于
enum
来说,此解决方法不适用,因为enum
类型中的静态字段无法在枚举本身之前移动(可能对于纯枚举)句法原因)。为了避免混淆,Java 对enum
添加了额外的限制 - 静态字段不能从构造函数中引用。这个限制是半途而废的。从构造函数中检查静态字段的所有可能用法并不容易(如果不是不可能的话)。以下代码将编译,打破限制:
Java allows this
Of course it'll have problem at runtime, but Java doesn't care. It's the job of the programmer to arrange init sequences, and it is not easy for compiler to check all broken init dependencies. The problem is easy to fix anyway:
But for
enum
, this workaround does not apply, because the static fields in anenum
type cannot be moved before enums themselves (probably for pure syntactic reason). To avoid confusion, Java adds an additional restriction forenum
- static fields cannot be referenced from constructor.This restriction is half-assed. It's not easy (if not impossible) to check all possible usages of static fields from constructor. The following code would compile, defeating the restriction:
讨论和可能的解决方法
Discussion and Possible workaround