Java Enums可以有行为吗?

时间:2009-04-07 14:51:42

标签: java oop enums

在Java中,Enum可以完成Enums所做的伟大事情,但也可以拥有方法(行为和逻辑)。与使用枚举的类相比,它有什么优势?用来说明这一点的简单例子也是受欢迎的。

7 个答案:

答案 0 :(得分:16)

这是一个简单的例子:

enum RoundingMode {
    UP {
        public double round(double d) {
            return Math.ceil(d);
        }
    },
    DOWN {
        public double round(double d) {
            return Math.floor(d);
        }
    };

    public abstract double round(double d);
}

答案 1 :(得分:9)

Enum类型也是实现真正单身人士的好方法。

Java中的经典单例模式通常涉及私有构造函数和公共静态工厂方法,但仍然容易通过反射或(反)序列化实例化。枚举类型可以防止这种情况发生。

答案 2 :(得分:7)

我不太确定问题的标题在哪里与其余部分相符。是的,Java枚举有行为。他们也可以有状态,虽然它应该真的,真的是不可变的状态。 (可变的枚举值的想法是非常可怕的IMO。)

Java中的枚举基本上是一组固定的对象。好处是你知道,如果你有这种类型的引用,它总是 null或其中一个众所周知的集合。

我个人非常喜欢Java enums,并希望C#也拥有它们 - 它们比C#的枚举更加面向对象,这些枚举基本上都是“命名数字”。在初始化顺序方面存在一些“问题”,但它们通常都是晶圆厂。

答案 3 :(得分:2)

因为枚举实例是单例,所以您可以在switch语句或==中使用它们来检查相等性。

答案 4 :(得分:2)

基本上,Java枚举类(我不认为字节码级别存在差异),还有一个已知固定的可能实例集并且能够使用的额外好处他们在switch语句中。

您可以使用常规类(无数书籍和文章中描述的“类型安全枚举”模式)模拟“已知固定的可能实例集”,但是为了使其工作,这是相当多的工作(对每个这样的类重复)关于Serialization,equals()和hashCode(),以及其他一些我忘记的事情,这是非常正确的。语言级枚举使您无需工作。并且,如上所述,只能在switch语句中使用语言级枚举。

答案 5 :(得分:1)

在我们的项目中,我们使用枚举来做一些事情,但也许最突出的是用于i18n目的 - 每一段显示的文本都给出了一个枚举。 Enum类有一个String-returns方法,用于检查正在使用的Locale,并在运行时从一组翻译中选择正确的翻译。

这是一个双重用途 - 您可以从IDE获得代码完成,也永远不会忘记翻译字符串。

用法非常简单,以至于给出一个例子几乎是非常重要的,但这里有人如何使用翻译枚举

System.out.println(Translations.GREET_PERSON.trans()+" "+user.getName());

或者,如果你想要花哨,请让Enum接受参数,这将通过一些魔术字符串操作插入翻译字符串中的标记位置

System.out.println(Translations.GREET_PERSON.trans(user.getName());

答案 6 :(得分:0)

看看java / joda时间类,其中enums做了很多工作。

以下是java.time.Month:

的示例
public enum Month implements TemporalAccessor, TemporalAdjuster {
    JANUARY,
    FEBRUARY,
    MARCH,
    APRIL,
    MAY,
    JUNE,
    JULY,
    AUGUST,
    SEPTEMBER,
    OCTOBER,
    NOVEMBER,
    DECEMBER;

    private static final Month[] ENUMS = Month.values();

    public static Month of(int month) {
        if (month < 1 || month > 12) {
            throw new DateTimeException("Invalid value for MonthOfYear: " + month);
        }
        return ENUMS[month - 1];
    }

    // About a dozen of other useful methods go here 

}