Java enum-зачем использовать toString вместо name
Если вы посмотрите в перечислении api на метод name() Он говорит, что:
возвращает имя этой константы перечисления, точно как объявлено в ее объявлении перечисления.
Большинство программистов должны использовать метод toString в предпочтении к этому,
поскольку метод toString может возвращать более удобное имя.
Этот метод предназначен в первую очередь для использования в специализированных ситуациях, где правильность зависит от получения точного названия, которое не будет меняться от выпуска к выпуску.
почему лучше использовать toString()? Я имею в виду, что toString может быть переопределен, когда name() уже является окончательным. Поэтому, если вы используете toString и кто-то переопределяет его, чтобы вернуть жестко закодированное значение, все ваше приложение не работает... Также, если вы посмотрите в источниках, метод toString () возвращает точно и только имя. Это одно и то же.
6 ответов:
Это действительно зависит от того, что вы хотите делать с возвращаемым значением:
- Если вам нужно получить точное имя, используемое для объявления константы перечисления, вы должны использовать
name()какtoStringможет быть переопределен- если вы хотите напечатать константу перечисления удобным для пользователя способом, вы должны использовать
toStringкоторый, возможно, был переопределен (или нет!).когда я чувствую, что это может быть запутанным, я предоставляю более конкретный
getXXXспособ, для пример:public enum Fields { LAST_NAME("Last Name"), FIRST_NAME("First Name"); private final String fieldDescription; private Fields(String value) { fieldDescription = value; } public String getFieldDescription() { return fieldDescription; } }
использовать
name()когда вы хотите сделать сравнение или использовать жестко закодированные значения для внутреннего использования в коде.использовать
toString()когда вы хотите представить информацию пользователю (включая разработчика, смотрящего на журнал). Никогда не полагайтесь в своем коде наtoString()давая определенное значение. Никогда не тестируйте его против определенной строки. Если ваш код ломается, когда кто-то правильно изменяетtoString()возвращение, то он уже был сломан.из javadoc (акцент мой) :
возвращает строковое представление объекта. В общем, toString метод возвращает строку "дословно обозначает" этот объект. Результатом должно быть краткое, но информативное представление это легко для человек читать. рекомендуется всем подклассы переопределяют этот метод.
name()- это "встроенный" способenum. Это окончательно, и вы не можете изменить его реализацию. Он возвращает имя константы перечисления по мере ее записи, например, в верхнем регистре, без пробелов и т. д.сравнить
MOBILE_PHONE_NUMBERиMobile phone number. Какая версия более удобочитаема? Я верю во второе. Вот в чем разница:name()всегда возвращаетMOBILE_PHONE_NUMBER,toString()может быть overriden, чтобы вернутьMobile phone number.
в то время как большинство людей слепо следуют совету javadoc, есть очень конкретные ситуации, когда вы хотите на самом деле избежать toString(). Например, я использую перечисления в мой Java-код, но они должны быть сериализованы в базу данных, и обратно. Если бы я использовал toString (), то я технически был бы подвержен получению переопределенного поведения, как указывали другие.
дополнительно можно десериализации из базы данных, например, это всегда должно работать в Java:
MyEnum taco = MyEnum.valueOf(MyEnum.TACO.name());в то время как это не гарантируется:
MyEnum taco = MyEnum.valueOf(MyEnum.TACO.toString());кстати, мне кажется очень странным, что Javadoc явно говорит:"большинство программистов должны". Я нахожу очень мало прецедентов в toString перечисления, если люди используют это для "дружественного имени", это явно плохой прецедент, поскольку они должны использовать что-то более совместимое с i18n, что в большинстве случаев будет использовать метод name ().
name () - это буквально текстовое имя в коде java перечисления. Это означает, что он ограничен строками, которые могут фактически отображаться в вашем коде java, но не все желаемые строки могут быть выражены в коде. Например, вам может понадобиться строка, которая начинается с числа. имя() никогда не сможет получить эту строку для вас.
практический пример, когда name() и toString() имеют смысл быть разными,-это шаблон, в котором однозначное перечисление используется для определения синглтона. Сначала это выглядит удивительно, но имеет большой смысл:
enum SingletonComponent { INSTANCE(/*..configuration...*/); /* ...behavior... */ @Override String toString() { return "SingletonComponent"; // better than default "INSTANCE" } }в таком случае:
SingletonComponent myComponent = SingletonComponent.INSTANCE; assertThat(myComponent.name()).isEqualTo("INSTANCE"); // blah assertThat(myComponent.toString()).isEqualTo("SingletonComponent"); // better
Comments