为什么当我定义枚举时,我传递一个字段名称列表,然后不知何故那些字段名称(例如Days.MONDAY)最终引用字段值?我可以传递一个字段(例如Days.MONDAY)然后使用开关来获取字段值。更奇怪的是,当我声明枚举字段时,我甚至不必将名字放在引号中,即使它们实际上是值。
答案 0 :(得分:5)
Java中的枚举与其他语言中的枚举不同。他们需要一些使用。从本质上讲,枚举是一个特殊的类,你声明的每个枚举都是该类的一个对象:
public enum Day {
MONDAY, TUESDAY, WEDNESDAY
}
MONDAY,TUESDAY和WEDNESDAY是Class Day的对象,使用普通类可以获得几乎相同的效果,但是enum语法明确了你的意图。此外,您无法在其他地方创建THURSDAY - 仅在枚举括号内。这意味着编译器始终知道枚举值的完整列表,并允许Java在switch语句等地方使用枚举,因为编译器具有创建跳转表和检查代码正确性所需的所有信息。
因此,MONDAY 不某个整数值的标签,例如其他语言的枚举。它是一个像任何其他Java对象一样的对象。这就是为什么你不把它们放在引号中。这就像写作:
final static Day MONDAY = new Day();
final static Day TUESDAY = new Day();
等等。你甚至可以做这样的技巧:
public enum Day {
MONDAY("Mon", false), TUESDAY("Tue", false), WEDNESDAY("Wed", true);
private String shortForm = null;
private boolean humpDay = false;
Day(String shortForm, boolean humpDay) {
this.shortForm = shortForm;
this.humpDay=humpDay;
}
public String getShortForm() {
return shortForm;
}
public boolean isHumpDay() {
return humpDay;
}
}
每个星期一,星期二,星期三都是Day的对象,每个都有自己的成员,包括shortForm和humpDay。甚至还有一个构造函数。看到?对象,而不是值。
需要TUESDAY的简短表格吗?只需要做TUESDAY.getShortForm()。你不能用其他语言中的重新标记整数常数范式来做到这一点。
我希望有所帮助。 Java枚举非常强大,但对于习惯于使用其他语言的枚举的人来说,直到他们有突破性的时刻(“我现在看到它们!它们就像对象声明!”)可能会让人感到困惑。
答案 1 :(得分:3)
将Java枚举视为定义类的一种很好的语法。这是一个可能有帮助的shell脚本:
$ cat > Direction.java
public enum Direction {NORTH, EAST, SOUTH, WEST}
$ javac Direction.java
$ javap Direction
Compiled from "Direction.java"
public final class Direction extends java.lang.Enum{
public static final Direction NORTH;
public static final Direction EAST;
public static final Direction SOUTH;
public static final Direction WEST;
public static Direction[] values();
public static Direction valueOf(java.lang.String);
static {};
}
是的,您可以说EAST
是类Direction
的字段,其值是类Direction
的实例。我们将此值称为Direction.EAST
,与通过任何其他类的静态字段引用值的方式相同。
也许这种混淆是由于您没有看到像
这样的声明public static final Direction.EAST = SOMETHING_OR_OTHER_HERE;
这是可以理解的。枚举用于初始化这些字段值,但您不必自己显式初始化它们。就像你说的那样
public static final Direction.EAST = new Direction();
事实上,它是所谓的“Typesafe Enum”模式的一部分,它在Java获得当前枚举语法之前通常使用。
关于你对引号的评论,根本没有理由引用任何内容,因为没有涉及字符串。
关于你关于开关的评论,是的,字段名称和字段值的概念如何在这里发挥作用有点有趣。但这只是因为该值看起来像字段。换句话说,EAST
中的字段Direction
的值就是Direction.EAST
。但是,如果你考虑它,它与文字没有太大区别。您可能会问Float.NaN
的价值是多少?嗯,它是...... Float.NaN
。一种不透明的价值。
答案 2 :(得分:-1)
我认为enum的方式是它只是一个具有别名的唯一值的“列表” - 名称。几天你可以有从1到7的整数数组,但是在你的代码中,将名称分配给代表对象的事物,即星期一,星期二等,会更方便。等等你也可以为每一天宣布常量一周,但你必须输入更多的代码。 enum似乎没有像类那样引入一些新的编程范例,只是一个方便的快捷工具。