与Enum类型混淆

为什么当我定义一个枚举时,我传递一个字段名称列表,然后以某种方式那些字段名称(例如Days.MONDAY)最终引用字段 ? 我可以传递一个字段(例如Days.MONDAY),然后使用开关来获取字段值。 更奇怪的是,当我声明枚举字段时,我甚至不必将名称放在引号中,即使它们实际上是值。

将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获得当前枚举语法之前通常使用。

关于你对引用的评论,没有理由引用任何东西,因为没有涉及到任何字符串。

关于你关于开关的评论,是的,字段名称和字段值的概念如何发挥在这里有点有趣。 但这仅仅是因为该值看起来像字段。 换句话说, Direction的字段EAST的值是Direction.EAST 。 但是,如果你考虑它,它与文字没有太大区别。 您可能会问Float.NaN的价值是多少? 好吧,它是…. Float.NaN 。 一种不透明的价值。

Java中的枚举与其他语言中的枚举不同。 他们需要一些使用。 从本质上讲,枚举是一个特殊的类,你声明的每个枚举都是该类的一个对象:

 public enum Day { MONDAY, TUESDAY, WEDNESDAY } 

星期一,星期二和星期天是星期日的对象,使用普通类可以获得几乎相同的效果,但枚举语法明确指出了你的意图。 此外,您无法在其他地方创建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枚举非常强大,但对于习惯于使用其他语言的枚举的人来说,直到他们有突破性的时刻(“我现在看到它们!它们就像对象声明!”)可能会令人困惑。

我认为enum的方式是它只是一个具有别名的唯一值的“列表” – 名称。 几天你可以有从1到7的整数数组,但是在你的代码中,将名称分配给代表对象的事物(即星期一,星期二等)会更方便。等等你也可以为每一天宣布常量一周,但你必须输入更多的代码。 enum似乎没有像类那样引入一些新的编程范例,只是一个方便的快捷工具。