Java: возникают проблемы с объявлением перечисления с целочисленными константами - PullRequest
4 голосов
/ 26 августа 2010

Ух, я немного растерялся из-за того, как перечисления работают в Java. В C # и C ++ (что я обычно использую) это кажется нормальным, но Java хочет разозлиться на меня>.>

   enum Direction
   {
      NORTH_WEST = 0x0C,
      NORTH      = 0x10,
      NORTH_EAST = 0x14,
      WEST       = 0x18,
      NONE       = 0x20,
      EAST       = 0x28,
      SOUTH_WEST = 0x24,
      SOUTH      = 0x30,
      SOUTH_EAST = 0x3C
   }

Может кто-нибудь сказать мне, что я делаю не так? Спасибо

Вот ошибки:

 ----jGRASP exec: javac -g Test.java

Test.java:79: ',', '}', or ';' expected
      NORTH_WEST = 0x0C,
                 ^
Test.java:79: '}' expected
      NORTH_WEST = 0x0C,
                  ^
Test.java:80: <identifier> expected
      NORTH      = 0x10,
           ^
Test.java:87: ';' expected
      SOUTH_EAST = 0x3C
                       ^

Ответы [ 3 ]

22 голосов
/ 26 августа 2010

Для этого сценария похоже, что вы можете просто использовать поле экземпляра .

public enum Direction {
   NORTH(0x10), WEST(0x18), ...;

   private final int code;
   Direction(int code)  { this.code = code; }
   public int getCode() { return code; }
}

Java enum реализованы как объекты. У них могут быть поля и методы. У вас также есть возможность объявить конструктор, который принимает некоторые аргументы, и предоставить значения для этих аргументов в вашем постоянном объявлении. Вы можете использовать эти значения для инициализации любых объявленных полей.

Смотри также


Приложение: EnumSet и EnumMap

Обратите внимание, что в зависимости от того, что это за значения, у вас может быть даже лучшая опция, чем у полей экземпляра. То есть, если вы пытаетесь установить значения для битовых полей, вы должны просто использовать EnumSet.

Обычно можно видеть степени двух констант, скажем, в C ++, которые будут использоваться вместе с побитовыми операциями как компактное представление набора.

// "before" implementation, with bitwise operations

public static final int BUTTON_A = 0x01;
public static final int BUTTON_B = 0x02;
public static final int BUTTON_X = 0x04;
public static final int BUTTON_Y = 0x08;

int buttonState = BUTTON_A | BUTTON_X; // A & X are pressed!

if ((buttonState & BUTTON_B) != 0) ...   // B is pressed...

С enum и EnumSet это может выглядеть примерно так:

// "after" implementation, with enum and EnumSet

enum Button { A, B, X, Y; }

Set<Button> buttonState = EnumSet.of(Button.A, Button.X); // A & X are pressed!

if (buttonState.contains(Button.B)) ... // B is pressed...

Существует также EnumMap, который вы можете использовать. Это Map с ключами enum констант.

Итак, где, как и раньше, у вас может быть что-то подобное:

// "before", with int constants and array indexing

public static final int JANUARY = 0; ...

Employee[] employeeOfTheMonth = ...

employeeOfTheMonth[JANUARY] = jamesBond;

Теперь вы можете иметь:

// "after", with enum and EnumMap

enum Month { JANUARY, ... }

Map<Month, Employee> employeeOfTheMonth = ...

employeeOfTheMonth.put(Month.JANUARY, jamesBond);

В Java enum - очень мощная абстракция, которая также хорошо работает с Java Collections Framework.

Смотри также

  • Учебники по Java / Структура коллекций
  • Effective Java 2nd Edition
    • Элемент 30: используйте enum вместо int констант
    • Элемент 31: Использовать поля экземпляра вместо ординалов
    • Элемент 32: использовать EnumSet вместо битовых полей
    • Элемент 33: используйте EnumMap вместо порядкового индекса

Похожие вопросы

12 голосов
/ 26 августа 2010

В Java перечисления не содержат никаких других значений по умолчанию. Вам нужно создать личное поле для хранения одного. Попробуйте что-то вроде этого

enum Direction {
   NORTH_WEST(0x0C),
   NORTH(0x10),
   ...

   private final int code;
   private Direction(int code) {
       this.code = code;
   }
}

При необходимости добавить геттер.

0 голосов
/ 03 октября 2018

, если у вас есть Java 8 и у вас есть собственный набор инструментов. Затем вот инструмент, который вы можете добавить:

  • Интерфейс в стиле Java 8

    public interface IntEnumInterface
    {
        // Will MAP all your application Enums (of type integer)
        final static Map<String, IntEnumInterfaceHelper> enumHelpers = new HashMap<String, IntEnumInterfaceHelper>();
        // Ensure Enum unique name accross your application
        default String getEnumUniqueName() { return this.getClass().getCanonicalName() + ":" + this.toString(); }
    
        default void init(int value)
        {
            IntEnumInterfaceHelper h = new IntEnumInterfaceHelper(){};
            h.init(value);
            enumHelpers.put(getEnumUniqueName(), h);
        }
    
        // Access the linked helper to retrieve integer value
        default public int getId() { return enumHelpers.get(getEnumUniqueName()).getValue(); }
    
        // helper (pseudo abstract)
        abstract class IntEnumInterfaceHelper
        {
            private int intValue;
            public void init(int value) { intValue = value; }
            public int getValue() { return intValue; }
        };
    }
    
  • Теперь вы можете определять свои перечисления следующим образом:

    public enum RecordStatus implements IntEnumInterface
    {
        NEW(1), PROCESSING(2) ,PROCESS_COMPLETE(3), TO_DELETE(0);
        RecordStatus(int id) { init(id); }
    }
    
  • Затем получите числовые значения перечисления с помощью:

    System.out.println(RecordStatus.NEW.getId());
    System.out.println(RecordStatus.PROCESSING.getId());
    System.out.println(RecordStatus.PROCESS_COMPLETE.getId());
    System.out.println(RecordStatus.TO_DELETE.getId());
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...