Java enum-зачем использовать toString вместо name



Если вы посмотрите в перечислении api на метод name() Он говорит, что:




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




почему лучше использовать toString()? Я имею в виду, что toString может быть переопределен, когда name() уже является окончательным. Поэтому, если вы используете toString и кто-то переопределяет его, чтобы вернуть жестко закодированное значение, все ваше приложение не работает... Также, если вы посмотрите в источниках, метод toString () возвращает точно и только имя. Это одно и то же.

486   6  

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

    Ничего не найдено.