Можно ли предположить, что перечисления Java автоматически увеличиваются на 1? - PullRequest
7 голосов
/ 08 марта 2012

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 (direction) {
    case LEFT:newdirection = Direction.UP;
    break;
  etc...
}

Есть несколько преимуществ использования ординалов:

  • более короткий код
  • более быстрый код (незначительный)
  • если направление добавлено (например, DOWN_LEFT), реализация не обязательно должна измениться, если вы поместите новое направление в нужное место

Что вы думаете?

Ответы [ 6 ]

8 голосов
/ 08 марта 2012

Да - см. javadoc :

Возвращает порядковый номер этой константы перечисления (ее позиция в объявлении перечисления, где начальной константе присвоен порядковый номер нуля).

7 голосов
/ 08 марта 2012

Да - но ваш код не должен полагаться на него, потому что тогда он сломается, когда кто-то вставит Caturday.

4 голосов
/ 08 марта 2012

Да, однако, полагаясь на это, ваш код становится хрупким.Если вы когда-либо измените порядок констант в перечислении или добавите между ними константы, порядковые номера некоторых из констант изменятся.Так, например, не стоит хранить порядковые номера в базе данных или файле, потому что если ваш исходный код изменится, данные в базе данных или файле больше не будут совместимы с вашим измененным кодом.* Более надежным решением является явное хранение кодов с каждой из ваших констант.Например:

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 голосов
/ 08 марта 2012

Вы также можете использовать индексы следующим образом:

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

  private int value;    

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

  public int getValue() {
    return value;
  }
}
2 голосов
/ 08 марта 2012

Да.Однако полагаться на это не лучшая идея, если вы когда-нибудь захотите изменить порядок или добавить новые перечисления в разных местах или если вы найдете причину изменить существующее значение.Я считаю, что лучше дать им фактическое значение / значение помимо их порядкового значения и имени.

1 голос
/ 08 марта 2012

Проблема с порядковыми номерами состоит в том, что они зависят от порядка объявления значений перечисления.Если в какой-то момент новое значение будет добавлено в перечисление, и оно будет добавлено в середине других, то порядковые номера изменятся, аннулируя весь код, который зависел от определенного порядкового значения.

Если вам абсолютно необходимоназначьте фиксированное число порядковому значению, это может быть полезно:

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 связан с каждым значением перечисления, и вы можете быть уверены, что оно всегда будетимеют одинаковое значение - переданное в конструкторе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...