我可以假设Java枚举自动递增1吗?

时间:2012-03-08 14:10:01

标签: java enumeration ordinal

Java声明初始值的序数为0.我可以假设当我创建这样的枚举时:

public enum Direction {MONDAY, TUESDAY, WEDNESDAY, THURSDAY, ...}

TUESDAY的序数始终为1,WEDNESDAY的序数始终为2,......?


我会更具体一点。我宣布了一个枚举:

public enum Direction {UP,RIGHT,DOWN,LEFT}

现在有一种转90度(顺时针)的方法。这是序数的一行:

direction = Direction.values()[direction.ordinal()+1 % Direction.values().length];

如果我不使用序数,我将不得不使用switch语句或条件:

switch (direction) {
    case LEFT:newdirection = Direction.UP;
    break;
  etc...
}

使用序数有几个好处:

  • 更短的代码
  • 更快的代码(疏忽)
  • 如果添加了方向(例如DOWN_LEFT),如果您将新方向放在正确的位置,则实施不一定要改变

您怎么看?

6 个答案:

答案 0 :(得分:8)

是的 - 请参阅javadoc

  

返回此枚举常量的序号(它在枚举声明中的位置,其中初始常量的序数为零)。

答案 1 :(得分:7)

是的 - 但是你的代码不应该依赖它,因为当有人插入Caturday时会破坏它。

答案 2 :(得分:4)

是的,但依赖于此会使您的代码变得脆弱。如果你改变了枚举中常量的顺序或者在它们之间添加常量,那么一些常量的序数就会改变。因此,例如在数据库或文件中存储序号不是一个好主意,因为如果源代码发生更改,数据库或文件中的数据将不再与您更改的代码兼容。

更强大的解决方案是使用每个常量显式存储代码。例如:

public enum Status {
    NEW(0),
    PROCESSING(1),
    OK(2),
    ERROR(99);

    private final int code;

    private Status(int code) {
        this.code = code;
    }

    // Get the code for an enum constant
    public int getCode() {
        return code;
    }

    // Given a code, get the corresponding enum constant
    public static Status fromCode(int code) {
        for (Status s : Status.values()) {
            if (s.code == code) {
                return s;
            }
        }

        throw new IllegalArgumentException("Invalid code: " + code);
    }
}

答案 3 :(得分:3)

您还可以强制执行以下索引:

enum Direction {
  MONDAY(1),
  TUESDAY(2);
  // etc...

  private int value;    

  private Direction(int value) {
    this.value = value;
  }

  public int getValue() {
    return value;
  }
}

答案 4 :(得分:2)

是。但是,如果您想要在不同的地方重新排序或添加新的枚举,或者如果您找到更改现有值的理由,那么依赖于此并不是最佳选择。我发现除了它们的序数值和名称之外,给它们一个实际的价值/意义更好。

答案 5 :(得分:1)

序数的问题在于它们取决于枚举值的声明顺序。如果在某个时刻将一个新值添加到枚举中,并将其添加到其他枚举的中间,那么序数将会更改,从而使所有依赖于特定序数值的代码无效。

如果绝对必须为序数值分配固定数字,则可能有用:

enum Directions {
    NORTH(1),
    SOUTH(2),
    WEST(3),
    EAST(4);
    private int code;
    Directions(int code) {
        this.code = code;
    }
    public int getCode() {
        return code;
    }
}

在上面的代码段中,code属性与每个枚举值相关联,您可以确定它始终具有相同的值 - 构造函数中传递的值。