Java中的枚举类型是否支持自增运算符++?

27

是否可以为枚举类型实现++运算符?

我使用枚举类型处理状态机的当前状态,希望能够使用++运算符。


如果你在谈论运算符重载,那么不,Java 不支持这个功能。 - BackSlash
6
请参考这个答案。请注意,枚举类型的常量是不可变的,所以++无法直接用于枚举类型。最好的做法是定义一个next()方法来返回下一个枚举值。 - Jim Garrison
4
这是一个误导性的比较:整数常量也是不可变的(++不会改变5所代表的含义),但++可以正常工作,因为它改变了你的本地变量“引用”的哪个整数。在枚举类型上使用++也可以做到同样的事情,通过将本地变量season从指向SPRING改为指向SUMMER来实现。 - amalloy
2个回答

60

你不能“递增”枚举类型,但是你可以获取下一个枚举值:

// MyEnum e;
MyEnum next = MyEnum.values()[e.ordinal() + 1];

但更好的方法是在枚举类型中创建一个实例方法。

请注意,对于最后一个枚举实例,没有“下一个”实例,处理有问题的下一个值的方式如何处理:

public enum MyEnum {

    Alpha,
    Bravo,
    Charlie {
        @Override
        public MyEnum next() {
            return null; // see below for options for this line
        };
    };

    public MyEnum next() {
        // No bounds checking required here, because the last instance overrides
        return values()[ordinal() + 1];
    }
}

那么你可以这样做:

// MyEnum e;
e = e.next();

实现重写next()方法的合理选择包括:

  • return null; // 没有“下一个”
  • return this; // 限制在最后一个实例
  • return values()[0]; // 循环到第一个
  • throw new RuntimeException(); // 或者子类,如NoSuchElementException

重写该方法可以避免生成values()数组并检查其长度的潜在成本。例如,对于最后一个实例没有覆盖它的next()实现可能是:

public MyEnum next() {
    if (ordinal() == values().length - 1)
        throw new NoSuchElementException();
    return values()[ordinal() + 1];
}

在这里,ordinal()values()都被调用了(通常)两次,这将比上面覆盖的版本执行成本更高。


2
你在next方法中真的需要那个MyEnum参数吗? - Michael Lang
2
@MichaelLang 糟糕 - 我一开始是用静态方法,后来改成了实例方法,但忘记删除参数了 :( 谢谢。 - Bohemian
1
Jim Garrison的答案(请参见他上面的链接)仅调用values()一次--每个调用都会复制数组。此外,它使用模运算符处理超过枚举结尾的递增。 - Andy Thomas
2
在最后一个枚举中进行覆盖是避免条件语句和每次调用只调用一次values()的好方法。我会记住这个模式。我知道过早优化的负面影响。但对于可能以我意料之外的方式使用的公共枚举,添加一个单独的字段声明对我来说是值得的。 - Andy Thomas
2
@peter 是的 - 谢谢你让我知道。实际上,这段代码需要比那更多的修复,我已经处理好了。 - Bohemian
显示剩余4条评论

4

不,Java不支持对任何用户定义的类型(包括枚举)进行自定义运算符重载。

但是,您可以在枚举类中定义一个方法来返回下一个枚举器。


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