Java枚举类型:功能

3
嗨,我很喜欢在Java中使用枚举类型来帮助代码的可读性和限制无效值。然而,有人告诉我Java中的enum可以做的不仅仅是创建一组可能的命名值。

请问有人能列出Java的枚举允许的基本功能以及示例或者其他获取更多信息的地方吗?

非常感谢, Black Vegetable

编辑: 正如建议的那样,这个问题应该是在询问Java中枚举和类之间有什么区别。我不知道它们是那样强大的? 那么它们的区别是什么呢?


3
列出它可以做什么并不是非常有用。它们几乎可以做类可以做的任何事情。因此,也许列出它们与类的区别将是有用的。 - Mark Peters
3个回答

4

Java的enum基本上是一个成熟的类。

您可以:

  • 声明方法和字段
  • 实现接口

但您不能:

  • 扩展类(因为enum已经隐式地扩展了java.lang.Enum,而Java仅支持单一实现继承)
  • 具有公共构造函数

它们具有:

  • 一些编译器生成的方法,如valueOfvalues
  • 一些额外的线程安全保证(单项枚举是在Java中实现单例的推荐方式)

3
枚举类型可以实现接口。 - Jason Hall
1
枚举中不能有公共构造函数。 - Marcelo
1
还要看一下EnumMap和EnumSet。 - planetjones

3
枚举(enum)和普通类之间的区别主要在于JVM对枚举处理时给出的保证。假设你有一个枚举类(MyEnum),其中包含值(VALUE1和VALUE2),你可以确保该枚举类的构造函数仅在JVM中执行两次*,在序列化和反序列化VALUE1和VALUE2时,您可以保证每次都会得到相同的对象,以便对象相等性有效(而对于其他类,则不能保证...例如"Foo" == new String("Foo")可能返回false)。此外,每个枚举类都扩展了Enum<T extends Enum<T>>,因此您可以根据需要以通用方式使用这些枚举类型(学会喜欢name()valueOf())。 *类加载器是棘手的问题...是的,在这里有一个小例外。

2

除了其他人已经提到的内容,它们还有很多用途。

让我再介绍一种你可以使用它们的方式。我将它们用作对象的原型。这样,我不需要在网络上发送整个对象,而只需发送一个原型标识符。下面是我从一个简单的游戏中编写的示例。

public enum SimpleUnits
{
    BROTHERHOOD_ELITE_TROOPER,
    CAPITOL_FREE_MARINE,
    IMPERIAL_BLOOD_BERET;

    public static SimpleUnit getUnit(SimpleUnits unit)
    {
        SimpleUnit result = null;
//      new SimpleUnit(enumeName, hpMax, speed, CC, MW, PW, LD, ST, MV, AC, W, A, COST);
        switch(unit)
        {
            case BROTHERHOOD_ELITE_TROOPER:
                result = new SimpleUnit(BROTHERHOOD_ELITE_TROOPER.name(), 5, 0.15, 12, 12, 12, 12, 3,
                        5, 3, 2, 1, 100, "images/units/eliteTrooper.png");
                break;
            case CAPITOL_FREE_MARINE:
                result = new SimpleUnit(CAPITOL_FREE_MARINE.name(), 5, 0.15, 12, 12, 12, 12, 3,
                        5, 3, 2, 1, 100, "images/units/freeMarine.png");
                break;
            case IMPERIAL_BLOOD_BERET:
                result = new SimpleUnit(IMPERIAL_BLOOD_BERET.name(), 5, 0.15, 12, 12, 12, 12, 3,
                        5, 3, 2, 1, 100, "images/units/bloodBeret.png");
                break;
        }
        return result;
    }

    public SimpleUnit getUnit()
    {
        return SimpleUnits.getUnit(this);
    }

    public static SimpleUnit getUnit(String enumeName)
    {
        return SimpleUnits.valueOf(enumeName).getUnit();
    }
}

希望您会发现它有用。

在这个例子中,“构造函数”参数的类型在哪里定义?顺便说一下,谢谢。 - BlackVegetable
1
@BlackVegetable,“SimpleUnit”基本上是一个“正式”的类。它在其他文件中定义。正如它所说,它描述了一个单位。我使用的命名方式是,只给枚举类型以复数名称,并且其名称对应于该枚举类型所服务的原型集合的类。 - Boro
我花了一会儿才明白。我喜欢这种风格。然而,我有另一个非常相关的问题,但我认为它不值得单独一页。如何包含特定于枚举的属性(变量)?也就是说,我想将其视为抽象类,并根据使用的枚举名称填写每个参数。 - BlackVegetable
1
由于枚举可以拥有自己的构造函数,您可以尝试使用它的构造函数来尝试一些解决方案,而不是使用我的方法。这里有一个关于行星的Java教程的好例子。 - Boro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接