Plusieurs fois, j'ai vu des gens utiliser des noms en majuscules ou même des minuscules pour les constantes enum, par exemple:
enum Color {
red,
yellow,
green;
}
Cela rend le travail avec leur forme de chaîne simple et facile, si vous voulez le faire throw new IllegalStateException("Light should not be " + color + ".")
, par exemple.
Cela semble plus acceptable si l'énumération l'est private
, mais je ne l'aime toujours pas. Je sais que je peux créer un constructeur enum avec un champ String, puis remplacer toString pour retourner ce nom, comme ceci:
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;
}
}
Mais regardez combien de temps cela dure. C'est ennuyeux de continuer à faire si vous avez un tas de petites énumérations que vous voulez garder simples. Est-il correct d'utiliser simplement des formats de cas non conventionnels ici?
la source
Light should not be RED.
. Après tout, ce message est destiné au développeur, l'utilisateur ne devrait jamais le voir.Light should not be YELLOW.
je suppose que c'est une constante quelconque, la méthode toString () est juste à des fins de débogage, donc je ne vois pas pourquoi vous devez changer à quoi il ressemble dans ce message.Réponses:
La réponse courte est, bien sûr, de savoir si vous voulez rompre avec les conventions de dénomination pour ce qui sont essentiellement des constantes ... Citant le JLS :
La réponse longue, en ce qui concerne l'utilisation de
toString()
, est que c'est certainement la méthode à remplacer si vous voulez une représentation plus lisible desenum
valeurs. Citant deObject.toString()
(soulignement le mien):Maintenant, je ne sais pas pourquoi certaines des réponses ont dérivé pour parler de la conversion en
enums
va-et-vient avec desString
valeurs, mais je vais juste donner mon avis ici également. Une telle sérialisation desenum
valeurs peut facilement être prise en charge en utilisant les méthodesname()
ouordinal()
. Les deux le sontfinal
et vous pouvez donc être sûr des valeurs renvoyées tant que les noms ou le positionnement des valeurs ne changent pas . Pour moi, c'est un marqueur assez clair.Ce que je comprends de ce qui précède est le suivant: aujourd'hui, vous voudrez peut-être décrire
YELLOW
simplement comme «jaune». Demain, vous voudrez peut-être le décrire comme "Pantone Minion Yellow" . Ces descriptions devraient être renvoyées après avoir appelétoString()
, et je ne m'attendrais pas à ce que l'unename()
ou l' autreordinal()
change. Si je le fais, c'est quelque chose que je dois résoudre au sein de ma base de code ou de mon équipe, et devient une question plus importante qu'un simpleenum
style de nommage .En conclusion, si tout ce que vous avez l'intention de faire est d'enregistrer une représentation plus lisible de vos
enum
valeurs, je vous suggérerai toujours de vous en tenir aux conventions, puis de passer outretoString()
. Si vous avez également l'intention de les sérialiser dans un fichier de données ou vers d'autres destinations non Java, vous avez toujours les méthodesname()
etordinal()
pour vous sauvegarder, il n'est donc pas nécessaire de s'inquiéter de la substitutiontoString()
.la source
Ne modifiez pas
ENUM
c'est juste une mauvaise odeur de code. Soit une énumération une énumération et une chaîne une chaîne.Utilisez plutôt un convertisseur CamelCase pour les valeurs de chaîne.
Il existe de nombreuses bibliothèques open source qui résolvent déjà ce problème pour Java.
http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/CaseFormat.html
la source
En envoyant des énumérations entre mon code Java et une base de données ou une application cliente, je finis souvent par lire et écrire les valeurs d'énumération sous forme de chaînes.
toString()
est appelé implicitement lors de la concaténation de chaînes. Remplacer toString () sur certaines énumérations signifiait que parfois je pouvais justeet parfois je devais me rappeler d'appeler
ce qui a conduit à des erreurs, donc je ne fais plus ça. En fait, je ne remplace aucune méthode sur Enum, car si vous les jetez dans suffisamment de code client, vous finirez par briser les attentes de quelqu'un.
Créez votre propre nouveau nom de méthode, comme
public String text()
outoEnglish()
ou quoi que ce soit.Voici une petite fonction d'aide qui pourrait vous éviter de taper si vous avez beaucoup d'énumérations comme ci-dessus:
Il est toujours facile d'appeler .toUpperCase () ou .toLowerCase () mais le retour en casse mixte peut être délicat. Considérez la couleur, "bleu de France". La France est toujours en majuscule, donc vous voudrez peut-être ajouter une méthode textLower () à votre énumération si vous rencontrez cela. Lorsque vous utilisez ce texte au début d'une phrase, par rapport au milieu d'une phrase, par rapport à un titre, vous pouvez voir comment une seule
toString()
méthode va échouer. Et cela ne touche même pas les caractères illégaux dans les identificateurs Java, ou qui sont difficiles à taper car ils ne sont pas représentés sur les claviers standard, ou les caractères qui n'ont pas de casse (Kanji, etc.).Il n'est pas si difficile de les utiliser correctement:
J'espère que cela démontre également pourquoi l'utilisation de valeurs d'énumération à casse mixte vous décevra également. Une dernière raison de conserver les majuscules avec des constantes enum soulignées est que cela suit le principe du moindre étonnement. Les gens s'y attendent, donc si vous faites quelque chose de différent, vous devrez toujours vous expliquer ou traiter avec des gens qui abusent de votre code.
la source
toString()
à une énumération n'a aucun sens pour moi. Si vous voulez le comportement par défaut garanti des noms d'énumération, utilisezname()
. Je ne trouve pas du tout "tentant" de compter surtoString()
pour fournir la bonne clévalueOf(String)
. Je suppose que si vous voulez protéger vos énumérations, c'est une chose, mais je ne pense pas que ce soit une raison suffisante pour recommander que vous ne deviez jamais passer outretoString()
.<input type='checkbox' value=" + MY_CONST1 + ">
, et parfois je devais me rappeler d'appeler<input type='checkbox' value=" + MY_CONST1.name() + ">
, ce qui entraînait des erreurs.S'il y a la moindre chance que ces représentations de chaînes puissent être stockées dans des endroits comme des bases de données ou des fichiers texte, alors les avoir liées aux constantes d'énumération réelles deviendra très problématique si vous avez besoin de refactoriser votre énumération.
Et si un jour vous décidez de renommer
Color.White
àColor.TitaniumWhite
tout , il y a des fichiers de données là - bas contenant « Blanc »?De plus, une fois que vous aurez commencé à convertir des constantes enum en chaînes, l'étape suivante sera de générer des chaînes pour que l'utilisateur puisse les voir, et le problème ici est, comme vous le savez sûrement déjà, que la syntaxe de java ne fonctionne pas. autoriser les espaces dans les identifiants. (Vous n'en aurez jamais
Color.Titanium White
.) Donc, comme vous aurez probablement besoin d'un mécanisme approprié pour générer des noms d'énumération à afficher à l'utilisateur, il est préférable d'éviter de compliquer inutilement votre énumération.Cela étant dit, vous pouvez bien sûr aller de l'avant et faire ce que vous pensiez faire, puis refaçonner votre énumération plus tard, pour passer des noms au constructeur, quand (et si) vous rencontrez des problèmes.
Vous pouvez raser quelques lignes de votre énumération avec constructeur en déclarant le
name
champpublic final
et en perdant le getter. (Quel est cet amour que les programmeurs Java ont envers les getters?)la source
public final static int white = 1;
oupublic final static String white = "white";
(à part la rupture de la convention à nouveau), cela perd la sécurité de type fournie par l'énumération.public final
champ d'instance qui est initialisé à partir du constructeur se comporte exactement comme un champ non final, sauf que vous ne pouvez pas lui affecter au moment de la compilation . Vous pouvez le modifier via la réflexion et tout le code qui s'y réfère commencera immédiatement à voir la nouvelle valeur.On peut dire que le fait de suivre la convention de dénomination UPPERCASE viole DRY . (Et YAGNI ). Par exemple, dans votre exemple de code # 2: "RED" et "red" sont répétés.
Alors, suivez-vous la convention officielle ou suivez-vous DRY? Ton appel.
Dans mon code, je suivrai DRY. Cependant, je mettrai un commentaire sur la classe Enum, en disant "pas tous en majuscules parce que (explication ici)"
la source