Что такое перечисления и почему они полезны?

сегодня я просматривал некоторые вопросы на этом сайте и я нашел упоминание о enum используется в паттерн Singleton о предполагаемых преимуществах безопасности потока к такому решению.

Я никогда не использовал enums и я программируем на Java уже более двух лет. И, очевидно, они сильно изменились. Теперь они даже делают полноценную поддержку ООП внутри себя.

теперь почему и для чего я должен использовать перечисление в изо дня в день Программирование?

23 ответов


вы всегда должны использовать перечисления, когда переменная (особенно параметр метода) может принимать только одно из небольшого набора возможных значений. Примерами могут быть константы типа (статус контракта: "постоянный"," временный"," ученик") или флаги ("выполнить сейчас","отложить выполнение").

если вы используете перечисления вместо целых чисел (или строковых кодов), вы увеличиваете проверку времени компиляции и избегаете ошибок при передаче недопустимых констант, и вы документируете, какие значения являются законными для использовать.

кстати, чрезмерное перечислений может означать, что ваши методы не слишком много (это часто лучше иметь несколько отдельных методов, а не один метод, который принимает несколько флагов, которые изменяют то, что он делает), но если вы должны использовать флаги и коды типов, перечислений путь.

в качестве примера, что лучше?

/** Counts number of foobangs.
 * @param type Type of foobangs to count. Can be 1=green foobangs,
 * 2=wrinkled foobangs, 3=sweet foobangs, 0=all types.
 * @return number of foobangs of type
 */
public int countFoobangs(int type)

и

/** Types of foobangs. */
public enum FB_TYPE {
 GREEN, WRINKLED, SWEET, 
 /** special type for all types combined */
 ALL;
}

/** Counts number of foobangs.
 * @param type Type of foobangs to count
 * @return number of foobangs of type
 */
public int countFoobangs(FB_TYPE type)

вызов метода, например:

int sweetFoobangCount = countFoobangs(3);
будет:
int sweetFoobangCount = countFoobangs(FB_TYPE.SWEET);

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

int sweetFoobangCount = countFoobangs(99);

больше невозможно.


зачем использовать любую функцию языка программирования? Причина у нас есть языки вообще для

  1. программисты эффективно и правильно экспресс-алгоритмы в форме, которую могут использовать компьютеры.
  2. сопровождающие, чтобы понять алгоритмы, другие написали и правильно внести изменения.

перечисления улучшают как вероятность правильности, так и читаемость без написания много шаблонных. Если ты ... желая написать шаблон, вы можете "имитировать" перечисления:

public class Color {
    private Color() {} // Prevent others from making colors.
    public static final Color RED = new Color();
    public static final Color AMBER = new Color();
    public static final Color GREEN = new Color();
}

теперь вы можете написать:

Color trafficLightColor = Color.RED;

шаблон выше имеет тот же эффект, что и

public enum Color { RED, AMBER, GREEN };

оба предоставляют одинаковый уровень проверки справки от компилятора. Boilerplate просто больше набирает. Но сохранение большого количества набора текста делает программиста более эффективное (см. 1), так что это достойная характеристика.

это стоит по крайней мере еще один причина тоже:

переключатель заявления

одно, что то static final перечисление моделирования выше делает не дать тебе приятно switch случаях. Для типов перечислений коммутатор Java использует тип своей переменной для вывода области случаев перечисления, поэтому для enum Color выше вам просто нужно сказать:

Color color = ... ;
switch (color) {
    case RED:
        ...
        break;
}

обратите внимание, что это не Color.RED в случаях. Если вы не используете перечисление, единственный способ использовать именованные величины с switch is что-то вроде:

public Class Color {
    public static final int RED = 0;
    public static final int AMBER = 1;
    public static final int GREEN = 2;
}

но теперь переменная для хранения цвета должна иметь тип int. Хорошая проверка компилятора перечисления и static final моделирование ушла. Не счастливый.

компромисс заключается в использовании скалярного члена в симуляции:

public class Color {
    public static final int RED_TAG = 1;
    public static final int AMBER_TAG = 2;
    public static final int GREEN_TAG = 3;

    public final int tag;

    private Color(int tag) { this.tag = tag; } 
    public static final Color RED = new Color(RED_TAG);
    public static final Color AMBER = new Color(AMBER_TAG);
    public static final Color GREEN = new Color(GREEN_TAG);
}

теперь:

Color color = ... ;
switch (color.tag) {
    case Color.RED_TAG:
        ...
        break;
}

но обратите внимание, еще более шаблонный!

использование перечисления в качестве синглтона

от boilerplate выше вы можете посмотрите, почему перечисление предоставляет способ реализации синглтона. Вместо того, чтобы писать:

public class SingletonClass {
    public static final void INSTANCE = new SingletonClass();
    private SingletonClass() {}

    // all the methods and instance data for the class here
}

и затем доступ к нему с

SingletonClass.INSTANCE

мы можем просто сказать

public enum SingletonClass {
    INSTANCE;

    // all the methods and instance data for the class here
}

что дает нам то же самое. Мы можем уйти с этим, потому что Java перечислений are реализовано как полные классы с небольшим синтаксическим сахаром, посыпанным сверху. Это снова менее шаблонно, но это не очевидно, если идиома вам не знакома. Я тоже не нравится тот факт, что вы получаете различные функции перечисления, хотя они не имеют большого смысла для синглтона: ord и values, etc. (На самом деле есть более сложная симуляция, где Color extends Integer это будет работать с switch, но это так сложно, что это еще более четко показывает, почему enum это лучшая идея.)

потокобезопасность

безопасность потока потенциальная проблема только когда синглеты созданы лениво без запирающий.

public class SingletonClass {
    private static SingletonClass INSTANCE;
    private SingletonClass() {}
    public SingletonClass getInstance() {
        if (INSTANCE == null) INSTANCE = new SingletonClass();
        return INSTANCE;
    }

    // all the methods and instance data for the class here
}

если многие потоки называют getInstance одновременно INSTANCE по-прежнему равно null, можно создать любое количество экземпляров. Это плохо. Единственное решение-добавить synchronized доступ для защиты переменной INSTANCE.

на static final код выше не имеет этой проблемы. Он создает экземпляр с нетерпением во время загрузки класса. Загрузка класса синхронизирована.

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


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

  1. наличие кода, в котором находятся данные (то есть в самом перечислении-или часто в константах перечисления, которые могут переопределять методы).
  2. реализация интерфейса (или более), чтобы не привязывать код клиента к перечислению (которое должно предоставлять только набор по умолчанию реализации.)

самым простым примером будет набор Comparator реализация:

enum StringComparator implements Comparator<String> {
    NATURAL {
        @Override
        public int compare(String s1, String s2) {
            return s1.compareTo(s2);
        }
    },
    REVERSE {
        @Override
        public int compare(String s1, String s2) {
            return NATURAL.compare(s2, s1);
        }
    },
    LENGTH {
        @Override
        public int compare(String s1, String s2) {
            return new Integer(s1.length()).compareTo(s2.length());
        }
    };
}

этот "шаблон" можно использовать в гораздо более сложных сценариях, широко используя все лакомства, которые поставляются с перечислением: итерация по экземплярам, опираясь на их неявный порядок, получение экземпляра по его имени, статические методы, обеспечивающие правильный экземпляр для определенных контекстов и т. д. И все же у вас есть все это скрыто за интерфейсом, так что ваш код будет работать с пользовательскими реализациями без изменений, если вы хотите что-то, что недоступно среди "параметров по умолчанию".

Я видел, что это успешно применяется для моделирования концепции гранулярности времени (ежедневно, еженедельно и т. д.) где вся логика была инкапсулирована в перечисление(выбор правильной гранулярности для заданного диапазона времени, конкретное поведение, связанное с каждой гранулярностью как постоянные методы и т. д.). И все же ... --2--> Как видно на уровне сервиса, это просто взаимодействие.


что-то ни один из других ответов не охватил, что делает перечисления особенно мощными являются способность иметь методы шаблона. Методы могут быть частью базового перечисления и переопределяться каждым типом. И, с поведением, прикрепленным к перечислению, он часто устраняет необходимость в конструкциях if-else или операторах switch как this сообщение в блоге демонстрирует - где enum.method() делает то, что первоначально было бы выполнено внутри условного. Тот же пример также показывает использование статического импорта с перечислениями, а также производство гораздо более чистого DSL-кода.

некоторые другие интересные качества включают в себя тот факт, что перечисления обеспечивают реализацию для equals(), toString() и hashCode() и реализовать Serializable и Comparable.

для полного изложения всего, что перечисления могут предложить, я настоятельно рекомендую Брюса Экеля мышление в Java 4th edition который посвящает целую главу этой теме. Особенно показательны примеры вовлекая камень, бумагу, ножницы (т. е. RoShamBo) игру в качестве перечислений.


Из Java документы -

вы должны использовать типы перечислений в любое время необходимо представить фиксированный набор константы. Это включает естественное перечисление типы, такие как планеты в нашей Солнечной системы и наборы данных, где вы знаете все возможные значения при компиляции например, выбор на меню, флаги командной строки, и так далее.

общим примером является замена класса набором частных статических конечных констант int (в пределах разумного количества констант) с типом перечисления. В принципе, если вы думаете, что знаете все возможные значения "что-то" во время компиляции, вы можете представить это как тип перечисления. Перечисления обеспечивают читаемость и гибкость над классом с константами.

несколько других преимуществ, которые я могу думать о типах перечислений. Они всегда являются одним экземпляром определенного класса перечислений (следовательно, концепция использования перечислений по мере поступления синглтона). Еще одно преимущество-вы можете использовать перечисления как тип в switch-case заявление. Также вы можете использовать toString () на перечислении, чтобы напечатать их как читаемые строки.


теперь почему и для чего я должен использовать enum в повседневной программирования?

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

ex:Locale.setDefault(Locale.US) читает лучше, чем Locale.setDefault(1) и обеспечивает использование фиксированного набора значений, показанного в IDE при добавлении . разделитель вместо всех чисел.


Enums перечислить фиксированный набор значений, в самопроверке способом.
Они делают ваш код более явным, а также менее подверженным ошибкам.

почему бы не использовать String или int, вместо Enum, для констант?

  1. компилятор не позволит опечатки, ни значения из фиксированного установить, как перечисления типы сами по себе. Последствия:
    • вам не придется писать предварительное условие (или инструкцию if), чтобы убедиться, что ваш аргумент находится в допустимом диапазоне.
    • на инвариант типа поставляется бесплатно.
  2. перечисления могут иметь поведение, как и любой другой класс.
  3. вам, вероятно, понадобится аналогичный объем памяти для использования Strings, во всяком случае (это зависит от сложности Enum).

кроме того, каждый из Enumэкземпляры-это класс, для которого вы можете определить его индивидуальное поведение.

плюс, они заверяют потокобезопасность при создании экземпляров (когда enum загружен), который видел большое применение в упрощении Синглтон Шаблон.

этот блог иллюстрирует некоторые из его приложений, таких как Государственную Машину для парсера.


полезно знать, что enums так же, как и другие классы с Constant и private constructor.

например,

public enum Weekday
{
  MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
} 

компилятор компилирует его следующим образом:

class Weekday extends Enum
{
  public static final Weekday MONDAY  = new Weekday( "MONDAY",   0 );
  public static final Weekday TUESDAY = new Weekday( "TUESDAY ", 1 );
  public static final Weekday WEDNESDAY= new Weekday( "WEDNESDAY", 2 );
  public static final Weekday THURSDAY= new Weekday( "THURSDAY", 3 );
  public static final Weekday FRIDAY= new Weekday( "FRIDAY", 4 );
  public static final Weekday SATURDAY= new Weekday( "SATURDAY", 5 );
  public static final Weekday SUNDAY= new Weekday( "SUNDAY", 6 );

  private Weekday( String s, int i )
  {
    super( s, i );
  }

  // other methods...
}

enum означает перечислението есть упоминание (ряда вещей) одно за другим.

An перечисление - тип данных, содержащий фиксированный набор констант.

или

An enum как class, с фиксированным набором экземпляров, известных во время компиляции.

например:

public class EnumExample {
    interface SeasonInt {
        String seasonDuration();
    }

    private enum Season implements SeasonInt {
        // except the enum constants remaining code looks same as class
        // enum constants are implicitly public static final we have used all caps to specify them like Constants in Java
        WINTER(88, "DEC - FEB"), SPRING(92, "MAR - JUN"), SUMMER(91, "JUN - AUG"), FALL(90, "SEP - NOV");

        private int days;
        private String months;

        Season(int days, String months) { // note: constructor is by default private 
            this.days = days;
            this.months = months;
        }

        @Override
        public String seasonDuration() {
            return this+" -> "+this.days + "days,   " + this.months+" months";
        }

    }
    public static void main(String[] args) {
        System.out.println(Season.SPRING.seasonDuration());
        for (Season season : Season.values()){
            System.out.println(season.seasonDuration());
        }

    }
}

преимущества перечисления:

  • перечисление улучшает безопасность типов при проверке во время компиляции, чтобы избежать ошибок во время выполнения.
  • перечисление можно легко использовать в switch
  • enum может быть пересечен
  • enum может иметь поля, конструкторы и методы
  • enum может реализовать много интерфейсов, но не может расширить какой-либо класс, потому что он внутренне расширяет класс Enum

на больше


помимо всего сказанного другими.. В более старом проекте, в котором я работал, много общения между сущностями(независимыми приложениями) использовало целые числа, которые представляли небольшой набор. Было полезно объявить набор как enum со статическими методами, чтобы получить enum объект value и viceversa. Код выглядел чище, переключался на удобство использования и упрощал запись в журналы.

enum ProtocolType {
    TCP_IP (1, "Transmission Control Protocol"), 
    IP (2, "Internet Protocol"), 
    UDP (3, "User Datagram Protocol");

    public int code;
    public String name;

    private ProtocolType(int code, String name) {
        this.code = code;
        this.name = name;
    }

    public static ProtocolType fromInt(int code) {
    switch(code) {
    case 1:
        return TCP_IP;
    case 2:
        return IP;
    case 3:
        return UDP;
    }

    // we had some exception handling for this
    // as the contract for these was between 2 independent applications
    // liable to change between versions (mostly adding new stuff)
    // but keeping it simple here.
    return null;
    }
}

создать enum объект из полученных значений (например, 1,2) с помощью ProtocolType.fromInt(2) Писать для журналов с помощью myEnumObj.name

надеюсь, что это помогает.


Что такое перечисление

  • enum-ключевое слово, определенное для перечисления нового типа данных. Typesafe перечисления должны использоваться свободно. В частности, они являются надежной альтернативой простым константам String или int, используемым в гораздо более старых API для представления наборов связанных элементов.

зачем использовать enum

  • перечисления неявно являются окончательными подклассами java.ленг.Перечислимые
  • если перечисление является членом класса, оно неявно static
  • new никогда не может использоваться с перечислением, даже в самом типе перечисления
  • name и valueOf просто используют текст констант перечисления, в то время как toString может быть переопределен для предоставления любого контента, если это необходимо
  • для констант перечисления, равно и == равно одному и тому же, и может использоваться взаимозаменяемо
  • константы перечисления неявно являются общедоступными статическими final

Примечание

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

перечисление наследует все методы Object класс и абстрактный класс Enum. Таким образом, вы можете использовать его методы для отражения, многопоточности, серилизации, сравнения и т. д. Если вы просто объявите статическую константу вместо перечисления, вы не сможете. Кроме того, значение перечисления также может быть передано слою DAO.

вот пример программы для демонстрации.

public enum State {

    Start("1"),
    Wait("1"),
    Notify("2"),
    NotifyAll("3"),
    Run("4"),
    SystemInatilize("5"),
    VendorInatilize("6"),
    test,
    FrameworkInatilize("7");

    public static State getState(String value) {
        return State.Wait;
    }

    private String value;
    State test;

    private State(String value) {
        this.value = value;
    }

    private State() {
    }

    public String getValue() {
        return value;
    }

    public void setCurrentState(State currentState) {
        test = currentState;
    }

    public boolean isNotify() {
        return this.equals(Notify);
    }
}

public class EnumTest {

    State test;

    public void setCurrentState(State currentState) {
        test = currentState;
    }

    public State getCurrentState() {
        return test;
    }

    public static void main(String[] args) {
        System.out.println(State.test);
        System.out.println(State.FrameworkInatilize);
        EnumTest test=new EnumTest();
        test.setCurrentState(State.Notify);
        test. stateSwitch();
    }

    public void stateSwitch() {
        switch (getCurrentState()) {
        case Notify:
            System.out.println("Notify");
            System.out.println(test.isNotify());
            break;
        default:
            break;
        }
    }
}

перечисление означает "перечисляемый тип". Это тип данных, имеющий фиксированный набор констант, которые вы определяете сами.


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

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

в противном случае вы можете использовать строки, как всегда (возможно, вы определили некоторые "соглашения" для своего приложения), и вы будете очень гибкими... но вы не получите 100% безопасности от опечаток на ваших строках, и вы поймете их только во время выполнения.


перечисление? Зачем его использовать? Я думаю, что это более понятно, когда вы будете его использовать. У меня такой же опыт.

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

теперь, если вы создаете перечисление как операцию:

public enum operation {
    create("1")
    delete("2")
    edit("3")
    read("4")

    // You may have is methods here
    public boolean isCreate() {
        return this.equals(create);
    }
    // More methods like the above can be written

}

теперь, вы можете объявить что-то вроде:

private operation currentOperation;

// And assign the value for it 
currentOperation = operation.create

Так что вы можете использовать его во многих отношениях. Всегда хорошо иметь перечисление для определенных вещей, поскольку операция базы данных в приведенном выше примере может управляться проверив currentOperation. Возможно, можно сказать,что это можно сделать и с переменными и целочисленными значениями. Но я считаю, что Enum-более безопасный и программистский способ.

другое дело: я думаю, что каждый программист любит boolean, не так ли? Потому что он может хранить только два значения, два определенных значения. Таким образом, Enum можно рассматривать как имеющий тот же тип объектов, где пользователь определит, сколько и какой тип значения он будет хранить, просто в немного по-другому. :)


Java позволяет ограничить переменную одним из нескольких предопределенных значений - другими словами, одним значением из перечисленного списка. Используя enums может помочь уменьшить ошибку в вашем коде. Вот пример enums вне класса:

enums coffeesize{BIG , HUGE , OVERWHELMING }; 
//This semicolon is optional.

это ограничивает coffeesize имеющие либо: BIG , HUGE или OVERWHELMING как переменная.


до сих пор мне никогда не приходилось использовать перечисления. Я читал о них с тех пор, как они были представлены в 1.5 или версии tiger, как ее называли в тот день. Они никогда не решали для меня "проблемы". Для тех, кто использует его (и я вижу, что многие из них делают), я уверен, что он определенно служит некоторые цель. Просто моему 2 фунта.


здесь много ответов, просто хочу указать два конкретных:

1) Использование в качестве констант в Switch-case заявление. Switch case не позволит вам использовать строковые объекты для case. Перечисления пригодятся. Еще:http://www.javabeat.net/2009/02/how-to-use-enum-in-switch/

2) реализации Singleton Design Pattern - перечисление снова приходит на помощь. Использование, здесь:каков наилучший подход для использования перечисления в качестве синглтона в Java?


что дало мне Ах-ха момент было это осознание: что перечисление имеет частный конструктор, доступный только через публичное перечисление:

enum RGB {
    RED("Red"), GREEN("Green"), BLUE("Blue");

    public static final String PREFIX = "color ";

    public String getRGBString() {
        return PREFIX + color;
    }

    String color;

    RGB(String color) {
        this.color = color;
    }
}

public class HelloWorld {
    public static void main(String[] args) {
        String c = RGB.RED.getRGBString();
        System.out.print("Hello " + c);
    }
}

Что касается меня, чтобы сделать код читаемым в будущем, самый полезный aplyable случай перечисления представлен в следующем фрагменте:

public enum Items {
    MESSAGES, CHATS, CITY_ONLINE, FRIENDS, PROFILE, SETTINGS, PEOPLE_SEARCH, CREATE_CHAT
}

@Override
public boolean onCreateOptionsMenu(Menu menuPrm) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menuPrm);
    View itemChooserLcl;
    for (int i = 0; i < menuPrm.size(); i++) {
        MenuItem itemLcl  = menuPrm.getItem(i);
            itemChooserLcl = itemLcl.getActionView();
            if (itemChooserLcl != null) {
                 //here Im marking each View' tag by enume values:
                itemChooserLcl.setTag(Items.values()[i]);
                itemChooserLcl.setOnClickListener(drawerMenuListener);
            }
        }
    return true;
}
private View.OnClickListener drawerMenuListener=new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Items tagLcl= (Items) v.getTag();
        switch (tagLcl){
            case MESSAGES: ;
            break;
            case CHATS : ;
            break;
            case CITY_ONLINE : ;
            break;
            case FRIENDS : ;
            break;
            case  PROFILE: ;
            break;
            case  SETTINGS: ;
            break;
            case  PEOPLE_SEARCH: ;
            break;
            case  CREATE_CHAT: ;
            break;
        }
    }
};

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

  • поддержка компилятора (сразу см. раздел проблемы с типом)
  • поддержка инструмента в IDEs (автоматическ-завершение в случае переключателя ...)

перечисления могут иметь методы, конструкторы, вы даже можете использовать перечисления внутри перечислений и комбинировать перечисления с интерфейсами.

подумайте о перечислениях как типах для замены хорошо определенного набора констант int (которые Java "унаследовал" от C / C++).

книги эффективное Java 2nd Edition есть целая глава о них и более детально. Также смотрите этот столб переполнения стека.


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

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

лучшим примером может быть что-то вроде типа категории продукта. Предположим, ваше программное обеспечение управляет запасами для универмага. Существует множество категорий продуктов и множество причин, по которым этот список категорий может измениться. Менеджеры могут хотеть чтобы запастись новой продуктовой линейкой, избавьтесь от других продуктовых линий и, возможно, время от времени реорганизуйте категории. Если вам нужно перестроить и повторно развернуть все ваши системы просто потому, что пользователи хотят добавить категорию продукта, то вы взяли что-то, что должно быть простым и быстрым (добавление категории) и сделало его очень сложным и медленным.

итог, перечисления хороши, если данные, которые вы представляете, очень статичны с течением времени и имеют ограниченное количество зависимостей. Но если данные сильно меняются и имеют много зависимостей, тогда вам нужно что-то динамическое, что не проверяется во время компиляции (например, таблица базы данных).


Я бы использовал перечисления в качестве полезного инструмента отображения, избегая нескольких if-else при условии реализации некоторых методов.

public enum Mapping {

    ONE("1"),
    TWO("2");

    private String label;

    private Mapping(String label){
        this.label = label;
    }

    public static Mapping by(String label) {

        for(Mapping m: values() {
            if(m.label.equals(label)) return m;
        }

        return null;
    }

}

Итак метод by(String label) позволяет получить перечисленное значение не перечисленным. Далее, можно придумать сопоставление 2 перечисления. Можно также попробовать "1 ко многим" или "многие ко многим" в дополнение к "Один к одному" по умолчанию отношение

в итоге enum - это Java-класс. Так что вы можете иметь main метод внутри него, который может быть полезен при необходимости выполнения некоторых операций отображения на args сразу.