7

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),如果您将新方向放在正确的位置,则实施不一定要更改

你怎么看?

4

6 回答 6

8

是的 - 请参阅javadoc

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

于 2012-03-08T14:13:56.467 回答
7

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

于 2012-03-08T14:14:16.747 回答
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);
    }
}
于 2012-03-08T14:23:12.670 回答
3

您还可以像这样强制执行索引:

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

  private int value;    

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

  public int getValue() {
    return value;
  }
}
于 2012-03-08T14:14:42.410 回答
2

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

于 2012-03-08T14:12:32.293 回答
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属性与每个枚举值相关联,您可以确定它始终具有相同的值——在构造函数中传递的那个值。

于 2012-03-08T14:28:17.207 回答