Подтвердить что ты не робот

Как определить свойства для элементов Enum

Я прочитал вопрос Разница Enum между java и С++?, но я все еще смущен.

Я хочу, чтобы следующее возвращало связанную строку:

public enum Checker {
    EMPTY ("Empty"),
    RED ("Red"),
    YELLOW ("Yellow");
}

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

4b9b3361

Ответ 1

Краткий ответ

Вам нужен конструктор, поле и получатель.

Конструкторы

Типы перечислений могут иметь конструкторы при условии, что их уровень доступа является либо закрытым, либо дефолтным (private-package). Вы не можете напрямую вызывать эти конструкторы, кроме самой декларации перечисления. Подобно классам, когда вы определяете константу enum без параметров, вы фактически вызываете конструктор по умолчанию, сгенерированный компилятором. Например.

public enum King{
    ELVIS
}

эквивалентно

public enum King{
    ELVIS() // the compiler will happily accept this
}

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

public enum King{
    ELVIS, // error, default constructor is not defined
    MICHAEL_JACKSON(true)
    ;
    private boolean kingOfPop;
    King(boolean kingOfPop){this.kingOfPop = kingOfPop;}
}

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

Поля и аксессуары

Перечисления являются константами и неизменны как таковые. Однако они могут определять поля, которые могут иметь состояние. Это ужасная практика, потому что разработчики ожидают, что перечисления и связанные с ними значения будут константами, но вы все равно можете определить не конечное поле в перечислении с помощью геттеров и сеттеров.

Это юридический код Java:

public enum Color{
    RED("FF0000"),
    GREEN("00FF00"),
    BLUE("0000FF");
    private String code;
    public String getCode(){return code;}
    public void setCode(String code){this.code = code;}
    private Color(String code){this.code = code;}
}

Но он позволяет злой код следующим образом:

String oldBlue = Color.BLUE.getCode();
Color.BLUE.setCode(Color.RED.getCode());
Color.RED.setCode(oldBlue);

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

public enum Band{
    THE_BEATLES("John","Paul","George","Ringo");
    private final List<String> members;
    public List<String> getMembers(){
        // defensive copy, because the original list is mutable
        return new ArrayList<String>(members);
    }
    private Band(String... members){
        this.members=Arrays.asList(members);
    }
}

Решение

В вашем случае это очень просто: вам просто нужно одно поле типа string (неизменяемое), поэтому инициализация его в конструкторе и предоставление getter вполне нормально:

public enum Checker {

    EMPTY ("Empty"),
    RED ("Red"),
    YELLOW ("Yellow");

    private final String value;

    private Checker(final String value) {
        this.value = value;
    }

    public String getValue() { return value; }
}

Ответ 2

Если шаблон сохраняется, это также работает и устраняет повторение:

public enum Checker {
    EMPTY,
    RED,
    YELLOW;


    public String getDescription(){
        String name = name();
        return ""+Character.toUpperCase(name.charAt(0))
                 +name.substring(1).toLowerCase();
    }

}