Несколько раз я видел, как люди используют заглавные или даже строчные имена для перечисления констант, например:
enum Color {
red,
yellow,
green;
}
Это делает работу с их строковой формой простой и легкой, например, если вы хотите throw new IllegalStateException("Light should not be " + color + ".")
.
Это кажется более приемлемым, если enum есть private
, но мне все еще не нравится. Я знаю, что могу сделать конструктор enum с полем String, а затем переопределить toString, чтобы вернуть это имя, например:
enum Color {
RED("red"),
YELLOW("yellow"),
GREEN("green");
private final String name;
private Color(String name) {
this.name = name
}
@Override public String toString() {
return name;
}
}
Но посмотрите, как долго это будет. Раздражать, если у вас есть небольшие перечисления, которые вы хотите сохранить простыми, раздражает. Можно ли здесь просто использовать нестандартные форматы?
java
conventions
enum
нарушитель закона
источник
источник
Light should not be RED.
. В конце концов, это сообщение для разработчика, пользователь никогда не должен его видеть.Light should not be YELLOW.
я бы предположил, что это какая-то константа, метод toString () предназначен только для целей отладки, поэтому я не понимаю, почему вам нужно изменить то, как он выглядит в этом сообщении.Ответы:
Краткий ответ, конечно, заключается в том, хотите ли вы порвать с соглашениями об именах для того, что по существу является константой ... Цитата из JLS :
Длинный ответ, касающийся использования
toString()
, - это, безусловно, метод переопределения, если вы хотите более читаемое представлениеenum
значений. Цитирую изObject.toString()
(выделено мое):Теперь я не уверен, почему некоторые из ответов сместились к разговору о том, как конвертировать
enums
туда-сюда соString
значениями, но я просто дам здесь мой взгляд. О такой сериализацииenum
значений можно легко позаботиться, используя методыname()
илиordinal()
. И то,final
и другое, и, таким образом, вы можете быть уверены в возвращаемых значениях, пока имена или расположение значений не меняются . Для меня это достаточно четкий маркер.Из вышесказанного я понял следующее: сегодня вы можете описать его
YELLOW
просто как «желтый». Завтра, возможно, вы захотите описать его как «Желтый цвет Pantone Minion» . Эти описания должны быть возвращены из вызоваtoString()
, и я бы не стал ожидать либоname()
илиordinal()
изменения. Если я это сделаю, это то, что мне нужно решить в моей кодовой базе или моей команде, и это станет большим вопросом, чем простоenum
стиль именования .В заключение, если все, что вы намереваетесь сделать, это записать более удобочитаемое представление ваших
enum
значений, я все равно предложу придерживаться соглашений и затем переопределитьtoString()
. Если вы намерены сериализации их в файл данных, или в другие места , не Java, вы по- прежнему естьname()
иordinal()
методы , чтобы поддержать вас, так что нет необходимости беспокоиться по поводу переопределениеtoString()
.источник
Не изменяйте
ENUM
это просто плохой запах кода. Пусть enum будет enum, а string - строкой.Вместо этого используйте конвертер CamelCase для строковых значений.
Есть много библиотек с открытым исходным кодом, которые уже решают эту проблему для Java.
http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/CaseFormat.html
источник
Отправляя перечисления между моим Java-кодом и базой данных или клиентским приложением, я часто заканчиваю тем, что читаю и записываю значения перечисления в виде строк.
toString()
вызывается неявно при конкатенации строк. Переопределение toString () в некоторых перечислениях означало, что иногда я мог простоа иногда мне приходилось не забывать звонить
что привело к ошибкам, поэтому я больше так не делаю. На самом деле, я не переопределяю никакие методы в Enum, потому что, если вы добавите их к достаточному количеству клиентского кода, вы в конечном итоге нарушите чьи-то ожидания.
Создайте свое собственное имя нового метода, например
public String text()
илиtoEnglish()
или как угодно.Вот небольшая вспомогательная функция, которая поможет вам сэкономить при наборе, если у вас много перечислений, как указано выше:
Всегда легко вызывать .toUpperCase () или .toLowerCase (), но вернуть смешанный регистр может быть сложно. Рассмотрим цвет "bleu de France". Франция всегда пишется с большой буквы, поэтому вы можете захотеть добавить метод textLower () к своему перечислению, если столкнетесь с этим. Когда вы используете этот текст в начале предложения по сравнению с серединой предложения или в заголовке, вы можете увидеть, как один
toString()
метод не справится с задачей. И это даже не касается символов, которые являются недопустимыми в идентификаторах Java, или которые неудобно набирать, потому что они не представлены на стандартных клавиатурах, или символы, которые не имеют регистра (кандзи и т. Д.).Это не так сложно использовать правильно:
Надеюсь, это также демонстрирует, почему использование перечислимых значений в смешанном регистре также разочарует вас. Одна из последних причин использовать заглавные буквы с подчеркивающими константами - это следовать принципу наименьшего удивления. Люди ожидают этого, поэтому, если вы делаете что-то другое, вам всегда придется объяснять себя или иметь дело с людьми, злоупотребляющими вашим кодом.
источник
toString()
перечисление не имеет смысла для меня. Если вы хотите гарантированное поведение по умолчанию имен enum, используйтеname()
. Я не нахожу заманчивым полагаться на то,toString()
чтобы предоставить правильный ключvalueOf(String)
. Я думаю, если вы хотите идиотизировать ваши перечисления, это одно, но я не думаю, что это достаточно веская причина, чтобы рекомендовать вам никогда не отменятьtoString()
.<input type='checkbox' value=" + MY_CONST1 + ">
, а иногда мне приходилось не забывать вызывать<input type='checkbox' value=" + MY_CONST1.name() + ">
, что приводило к ошибкам.Если есть малейшая вероятность того, что эти строковые представления могут быть сохранены в таких местах, как базы данных или текстовые файлы, то их привязка к фактическим константам перечисления станет очень проблематичной, если вам когда-либо понадобится провести рефакторинг вашего перечисления.
Что делать , если в один прекрасный день вы решили переименовать
Color.White
вColor.TitaniumWhite
то время как есть данные файлы из там содержащих «Белых»?Кроме того, как только вы начнете преобразовывать константы enum в строки, следующим шагом будет создание строк для просмотра пользователем, и проблема здесь, как я уверен, вы уже знаете, что синтаксис java не разрешить пробелы в идентификаторах. (Вы никогда этого не
Color.Titanium White
сделаете.) Итак, поскольку вам, вероятно, понадобится надлежащий механизм для генерации имен перечислений, чтобы показать их пользователю, лучше избегать ненужного усложнения вашего перечисления.Сказав это, вы, конечно, можете пойти дальше и сделать то, о чем вы думали, а затем реорганизовать свой enum позже, чтобы передать имена конструктору, когда (и если) у вас возникнут проблемы.
Вы можете убрать пару строк из вашего enum-with-constructor, объявив
name
полеpublic final
и потеряв геттер. (Что это за любовь к Java-программистам?)источник
public final static int white = 1;
илиpublic final static String white = "white";
(кроме нарушения соглашения снова), это теряет безопасность типов, которую обеспечивает enum.public final
Поле экземпляра , который инициализируется из конструкторы ведет себя так же , как неконечное поле, за исключение того, что вы предотвращены во время компиляции от присвоения ему. Вы можете изменить его с помощью отражения, и весь код, который ссылается на него, немедленно начнет видеть новое значение.Возможно, следование соглашению об именах UPPERCASE нарушает DRY . (И ЯГНИ ). Например, в вашем примере кода # 2: «КРАСНЫЙ» и «красный» повторяются.
Итак, вы следуете официальному соглашению или следите за DRY? Ваш звонок.
В моем коде я буду следовать DRY. Тем не менее, я добавлю комментарий к классу Enum, сказав, что «не все в верхнем регистре, потому что (объяснение здесь)»
источник