【问题标题】:Java Enumerated Types: FunctionalityJava 枚举类型:功能
【发布时间】:2011-05-28 14:12:50
【问题描述】:

嘿,我非常喜欢在 Java 中使用枚举类型来帮助提高代码的可读性和限制无效值。但是,有人告诉我,在 Java 中使用枚举可以做的事情远不止创建一组命名的可能值。

有人可以列出 Java 枚举所允许的基本功能,以及我可以获取有关该功能的更多信息的示例或位置吗?

非常感谢, 黑菜

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

【问题讨论】:

  • 我不认为列出它可以做什么真的很有用。他们几乎可以做任何班级可以做的事情。所以也许列出它们与一个类的区别会很有用。

标签: java enums


【解决方案1】:

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

您可以:

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

但你不能:

  • 扩展类(因为 enums 已经隐式扩展 java.lang.Enum 并且 Java 仅支持单一实现继承)
  • 有公共构造函数

他们有:

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

【讨论】:

  • 枚举可以实现接口。
  • 枚举中不能有公共构造函数。
  • 也看看 EnumMap 和 EnumSet
【解决方案2】:

枚举和普通类之间的区别主要在于 JVM 对枚举的处理为您提供的保证。

假设您有一个带有值(VALUE1 和 VALUE2)的枚举类 (MyEnum)。您可以保证该枚举类的构造函数只会在您的 JVM* 中执行两次,在序列化和反序列化 VALUE1 和 VALUE2 时,您可以保证每次都获得相同的对象,这样对象相等性就会起作用(而它不会保证与其他类...(例如 "Foo" == new String("Foo") 可能返回 false)。

此外,每个枚举类都扩展了Enum<T extends Enum<T>>,因此您可以根据需要以通用方式使用这些枚举类型(学会爱上name()valueOf())。

*类加载器是一项棘手的工作……是的,这里有一个小例外。

【讨论】:

    【解决方案3】:

    除了其他人已经说过的话,他们有很多东西。

    让我再介绍一种您可以为它们找到的用途。我将它们用作对象的原型。这种方式不是通过网络发送整个对象,而是发送一个原型标识符。下面我展示了一个取自我编写的简单游戏的示例,以供娱乐和练习。

    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 SimpleUnit 基本上是一个“适当的”类。这是在其他文件中定义的。正如它所说,它描述了一个单位。我使用的命名是,我只给枚举赋予复数名称,并且它的名称对应于枚举用作原型集合的类。
    • 我花了一点时间才明白这一点。我喜欢这种风格。但是,我确实有另一个非常相关的问题,但我认为它不值得拥有自己的页面。如何包含特定于枚举的属性(变量)?也就是我想把它当做一个抽象类,根据使用哪个枚举名来填写各个参数。
    • 由于枚举可以有自己的构造函数,你可以尝试一些使用它构造函数的解决方案,而不是我的方法。 There is a nice example in Java tutorials with planets, here.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-22
    • 1970-01-01
    • 2013-07-18
    • 2012-09-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多