繁体   English   中英

与枚举类型混淆

[英]Confusion with Enum type

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

Java中的枚举不同于其他语言中的枚举。 他们需要一些习惯。 本质上,一个枚举是一个特殊的类,并且您声明的每个枚举都是该类的一个对象:

public enum Day {

    MONDAY, TUESDAY, WEDNESDAY

}

MONDAY,TUESDAY和WEDNESDAY是Day类的对象,使用普通的类可以获得几乎相同的效果,但是enum语法明确表明了您的意图。 另外,您不能在其他地方创建THURSDAY-只能在枚举括号内创建。 这意味着编译器始终知道枚举值的完整列表,并且允许Java在开关语句等地方使用枚举,因为编译器具有创建跳转表和检查代码正确性所需的所有信息。 。

因此,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;
    }

}

MONDAY,TUESDAY,WEDNESDAY的每个都是Day的对象,每个都有它自己的成员,包括shortForm和humpDay。 甚至还有一个构造函数。 看到? 对象,而不是值。

需要星期二的简短形式吗? 只需执行TUESDAY.getShortForm()。 您无法使用其他语言的relabeled-integer-constant范式执行此操作。

希望对您有所帮助。 Java枚举功能异常强大,但是对于那些习惯于使用其他语言枚举的人来说,直到他们具有突破性的时刻(“我现在看到了!它们就像对象声明!”),它才会令人困惑。

将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 {};
}

所以可以,您可以说EASTDirection类的一个字段,其值是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 不透明值的种类。

我认为枚举的方式是,它只是一个唯一值的“列表”,具有为其分配的别名-名称。 几天里,您可以使用1到7的整数数组,但是在代码中,将名称分配给代表对象的事物(如星期一,星期二等)要方便得多。您还可以为每一天声明常量一周的时间,但您必须输入更多代码。 枚举似乎没有像class那样引入一些新的编程范例,而只是一种便捷的快捷方式工具。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM