web-dev-qa-db-fra.com

Java enum - pourquoi utiliser toString au lieu de name

Si vous regardez dans l'api enum à la méthode name(), il est écrit que:

Renvoie le nom de cette constante enum, exactement comme indiqué dans sa déclaration enum. La plupart des programmeurs doivent utiliser la méthode toString de préférence à celle-ci, car la méthode toString peut renvoyer un nom plus convivial. Cette méthode est principalement conçue pour être utilisée dans des situations spécialisées où la correction dépend du nom exact, qui ne variera pas d’une publication à l’autre.

Pourquoi est-il préférable d'utiliser toString()? Je veux dire que toString peut être remplacé lorsque name () est déjà final. Donc, si vous utilisez toString et que quelqu'un le substitue pour renvoyer une valeur codée en dur, votre application entière est en panne ... De même, si vous regardez dans les sources, la méthode toString () renvoie exactement le nom. C'est la même chose.

163
spauny

Cela dépend vraiment de ce que vous voulez faire avec la valeur renvoyée:

  • Si vous devez obtenir le nom exact utilisé pour déclarer la constante d’énumération, vous devez utiliser name() car toString a peut-être été remplacé.
  • Si vous souhaitez imprimer la constante d’énumération de manière conviviale, vous devez utiliser toString qui peut avoir été écrasé (ou non!).

Lorsque je sens que cela peut prêter à confusion, je fournis une méthode plus spécifique getXXX, par exemple:

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;
    }
}
190
assylias

Utilisez name() lorsque vous souhaitez effectuer une comparaison ou utilisez la valeur codée en dur pour une utilisation interne dans votre code.

Utilisez toString() lorsque vous souhaitez présenter des informations à un utilisateur (y compris un développeur consultant un journal). Ne vous fiez jamais dans votre code à toString() donnant une valeur spécifique. Ne le testez jamais avec une chaîne spécifique. Si votre code se brise lorsque quelqu'un modifie correctement le retour toString(), il était déjà rompu.

De la javadoc (mine d'emphase):

Retourne une représentation sous forme de chaîne de l'objet. En général, la méthode toString renvoie une chaîne qui "représente textuellement" cet objet. Le résultat devrait être une représentation concise mais informative facile à lire pour une personne . Il est recommandé que toutes les sous-classes remplacent cette méthode.

54
Denys Séguret

name() est une méthode "intégrée" de enum. C'est final et vous ne pouvez pas changer sa mise en œuvre. Elle retourne le nom de la constante enum comme il est écrit, par exemple. en majuscule, sans espaces, etc.

Comparez MOBILE_PHONE_NUMBER et Mobile phone number. Quelle version est la plus lisible? Je crois au deuxième. C'est la différence: name() retourne toujours MOBILE_PHONE_NUMBER, toString() peut être remplacé pour renvoyer Mobile phone number.

23
AlexR

Alors que la plupart des gens suivent aveuglément les conseils du javadoc, il existe des situations très spécifiques dans lesquelles vous souhaitez réellement éviter toString (). Par exemple, j'utilise des énumérations dans mon code Java, mais elles doivent être sérialisées dans une base de données, et inversement. Si j’utilisais toString (), je serais techniquement soumis au comportement surchargé, comme d’autres l'ont fait remarquer.

De plus, on peut également désérialiser de la base de données, par exemple, cela devrait toujours fonctionner en Java:

MyEnum taco = MyEnum.valueOf(MyEnum.TACO.name());

Considérant que ceci n'est pas garanti:

MyEnum taco = MyEnum.valueOf(MyEnum.TACO.toString());

En passant, je trouve très étrange que la Javadoc dise explicitement que "la plupart des programmeurs devraient". Je trouve très peu de cas d'utilisation dans une chaîne d'enum, si les gens l'utilisent pour un "nom convivial", il s'agit clairement d'un cas d'utilisation médiocre, car ils devraient utiliser quelque chose de plus compatible avec i18n, ce qui, dans la plupart des cas, utilisez la méthode name ().

13
coding

name () est littéralement le nom textuel dans le code Java de l'énum. Cela signifie qu'il est limité aux chaînes pouvant apparaître dans votre code Java, mais que toutes les chaînes souhaitables ne peuvent pas être exprimées dans le code. Par exemple, vous aurez peut-être besoin d'une chaîne commençant par un nombre. name () ne pourra jamais obtenir cette chaîne pour vous.

4
Intropy

Un exemple pratique lorsque name () et toString () ont un sens d'être différent est un modèle dans lequel une énumération à valeur unique est utilisée pour définir un singleton. Cela semble surprenant au début, mais cela a beaucoup de sens:

enum SingletonComponent {
    INSTANCE(/*..configuration...*/);

    /* ...behavior... */

    @Override
    String toString() {
      return "SingletonComponent"; // better than default "INSTANCE"
    }
}

Dans ce cas:

SingletonComponent myComponent = SingletonComponent.INSTANCE;
assertThat(myComponent.name()).isEqualTo("INSTANCE"); // blah
assertThat(myComponent.toString()).isEqualTo("SingletonComponent"); // better
4
Marcin