Как определить свойства для элементов Enum - PullRequest
52 голосов
/ 16 июня 2010

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

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

Ответы [ 2 ]

102 голосов
/ 16 июня 2010

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

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

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

Типы Enum могут иметь конструкторы, при условии, что их уровень доступа является частным илипо умолчанию (пакет-приват).Вы не можете напрямую вызывать эти конструкторы, кроме как в самом объявлении enum.Подобно классам, когда вы определяете константу 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 (неизменяемое), поэтому инициализируйтеэто в конструкторе и предоставлении геттера совершенно нормально:

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; }
}
4 голосов
/ 16 июня 2010

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

public enum Checker {
    EMPTY,
    RED,
    YELLOW;


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

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