Ich habe mehrmals gesehen, wie Leute Titel- oder sogar Kleinbuchstaben für Enum-Konstanten verwenden, zum Beispiel:
enum Color {
red,
yellow,
green;
}
Dies macht das Arbeiten mit ihrer Zeichenfolgenform einfach und leicht, wenn Sie dies throw new IllegalStateException("Light should not be " + color + ".")
beispielsweise tun möchten .
Dies scheint akzeptabler zu sein, wenn die Aufzählung ist private
, aber ich mag es immer noch nicht. Ich weiß, dass ich einen Enum-Konstruktor mit einem String-Feld erstellen und dann toString überschreiben kann, um diesen Namen wie folgt zurückzugeben:
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;
}
}
Aber schauen Sie, wie lange das noch dauert. Es ist ärgerlich, weiterzumachen, wenn Sie ein paar kleine Aufzählungen haben, die Sie einfach halten möchten. Ist es in Ordnung, hier nur unkonventionelle Fallformate zu verwenden?
quelle
Light should not be RED.
. Schließlich ist diese Nachricht für den Entwickler bestimmt, der Benutzer sollte sie niemals sehen.Light should not be YELLOW.
würde ich vermuten, dass es sich um eine Konstante handelt. Die toString () -Methode dient nur zu Debugging-Zwecken, sodass ich nicht verstehe, warum Sie das Aussehen in dieser Nachricht ändern müssen.Antworten:
Die kurze Antwort lautet natürlich, ob Sie mit Namenskonventionen für im Wesentlichen Konstanten brechen möchten ... Zitat aus dem JLS :
Die lange Antwort in Bezug auf die Verwendung von
toString()
ist, dass dies definitiv die Methode ist, die überschrieben werden muss, wenn Sie eine besser lesbare Darstellung derenum
Werte wünschen . Zitat ausObject.toString()
(Hervorhebung von mir):Jetzt bin ich mir nicht sicher, warum einige der Antworten darauf gerichtet waren, über das Konvertieren
enums
mitString
Werten hin und her zu sprechen , aber ich werde auch hier nur meine Meinung dazu abgeben . Eine solche Serialisierung vonenum
Werten kann leicht mit den Methodenname()
oder durchgeführtordinal()
werden. Beides istfinal
und somit können Sie sich der zurückgegebenen Werte sicher sein, solange sich die Namen oder die Position der Werte nicht ändern . Für mich ist das ein klarer Marker.Was ich aus dem Obigen zusammenfasse, ist: Heute möchten Sie es vielleicht
YELLOW
einfach als "gelb" beschreiben. Morgen möchten Sie es vielleicht als "Pantone Minion Yellow" beschreiben . Diese Beschreibungen sollten vom Anruf zurückgegeben werdentoString()
, und ich würde weder erwartenname()
nochordinal()
ändern. Wenn ich das tue, muss ich das in meiner Codebasis oder in meinem Team lösen und es wird zu einer größeren Frage als nur zu einemenum
Namensstil .Wenn Sie lediglich eine besser lesbare Darstellung Ihrer
enum
Werte protokollieren möchten, empfehle ich dennoch, sich an die Konventionen zu halten und diese dann zu überschreibentoString()
. Wenn Sie sie auch in eine Datendatei oder in andere Nicht-Java-Ziele serialisieren möchten, verfügen Sie weiterhin über die Methodenname()
undordinal()
, um Sie zu sichern, sodass Sie sich nicht über das Überschreiben ärgern müssentoString()
.quelle
Ändern Sie nicht,
ENUM
dass dies nur ein schlechter Codegeruch ist. Sei eine Aufzählung eine Aufzählung und eine Zeichenfolge eine Zeichenfolge.Verwenden Sie stattdessen einen CamelCase-Konverter für Zeichenfolgenwerte.
Es gibt viele Open Source-Bibliotheken, die dieses Problem bereits für Java lösen.
http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/CaseFormat.html
quelle
Wenn ich Enums zwischen meinem Java-Code und einer Datenbank oder Client-App sende, lese und schreibe ich die Enum-Werte häufig als Zeichenfolgen.
toString()
wird implizit aufgerufen, wenn Zeichenfolgen verkettet werden. Das Überschreiben von toString () in einigen Aufzählungen bedeutete, dass ich es manchmal einfach konnteund manchmal musste ich daran denken anzurufen
was zu Fehlern führte, also mache ich das nicht mehr. Eigentlich überschreibe ich keine Methoden in Enum, denn wenn Sie sie in genügend Client-Code umwandeln, werden Sie irgendwann die Erwartungen von jemandem brechen.
Machen Sie Ihren eigenen neuen Methodennamen, wie
public String text()
odertoEnglish()
oder was auch immer.Hier ist eine kleine Hilfsfunktion, die Ihnen das Tippen ersparen könnte, wenn Sie viele Aufzählungen wie die oben genannten haben:
Es ist immer einfach, .toUpperCase () oder .toLowerCase () aufzurufen, aber es kann schwierig sein, gemischte Groß- und Kleinschreibung zurückzugewinnen. Betrachten Sie die Farbe "bleu de France". Frankreich wird immer groß geschrieben, daher möchten Sie möglicherweise eine textLower () -Methode zu Ihrer Aufzählung hinzufügen, wenn Sie darauf stoßen. Wenn Sie diesen Text am Anfang eines Satzes oder in der Mitte eines Satzes oder in einem Titel verwenden, können Sie sehen, wie eine einzelne
toString()
Methode zu kurz kommt. Und das berührt nicht einmal Zeichen, die in Java-Bezeichnern illegal sind oder deren Eingabe schwierig ist, weil sie nicht auf Standardtastaturen dargestellt werden, oder Zeichen, die keine Groß- / Kleinschreibung haben (Kanji usw.).Es ist nicht so schwierig, diese richtig zu verwenden:
Hoffentlich zeigt dies auch, warum die Verwendung von Enum-Werten in gemischten Groß- und Kleinschreibung Sie ebenfalls enttäuschen wird. Ein letzter Grund, bei All-Caps mit Unterstreichungs-Enum-Konstanten zu bleiben, ist, dass dies dem Prinzip des geringsten Erstaunens folgt. Die Leute erwarten es. Wenn Sie also etwas anderes tun, müssen Sie sich immer selbst erklären oder mit Leuten umgehen, die Ihren Code missbrauchen.
quelle
toString()
eine Aufzählung niemals außer Kraft zu setzen, macht für mich keinen Sinn. Wenn Sie das garantierte Standardverhalten von Aufzählungsnamen möchten, verwenden Siename()
. Ich finde es überhaupt nicht "verlockend", sich darauftoString()
zu verlassen, den richtigen Schlüssel für zu liefernvalueOf(String)
. Ich denke, wenn Sie Ihre Aufzählungen idiotensicher machen wollen, ist das eine Sache, aber ich denke nicht, dass dies ein guter Grund ist, zu empfehlen, dass Sie niemals überschreiben solltentoString()
.<input type='checkbox' value=" + MY_CONST1 + ">
konnte und manchmal daran denken musste, aufzurufen<input type='checkbox' value=" + MY_CONST1.name() + ">
, was zu Fehlern führte.Wenn die geringste Wahrscheinlichkeit besteht, dass diese Zeichenfolgendarstellungen an Orten wie Datenbanken oder Textdateien gespeichert werden, ist es äußerst problematisch, sie an die tatsächlichen Aufzählungskonstanten zu binden, wenn Sie Ihre Aufzählung jemals umgestalten müssen.
Was passiert , wenn Sie einen Tag umbenennen entscheiden
Color.White
zu ,Color.TitaniumWhite
während es Datendateien da draußen „White“ enthalten?Sobald Sie mit der Konvertierung von Enum-Konstanten in Zeichenfolgen beginnen, besteht der nächste Schritt darin, Zeichenfolgen zu generieren, die der Benutzer sehen kann. Das Problem hier ist, wie Sie sicher bereits wissen, dass die Syntax von Java dies nicht tut Leerzeichen innerhalb von Bezeichnern zulassen. (Das werden Sie nie haben
Color.Titanium White
.) Da Sie wahrscheinlich einen geeigneten Mechanismus zum Generieren von Aufzählungsnamen benötigen, der dem Benutzer angezeigt wird, sollten Sie vermeiden, Ihre Aufzählung unnötig zu komplizieren.Nachdem dies gesagt wurde, können Sie natürlich weitermachen und das tun, woran Sie gedacht haben, und später Ihre Aufzählung umgestalten, um dem Konstruktor Namen zu geben, wenn (und wenn) Sie in Schwierigkeiten geraten.
Sie können ein paar Zeilen von Ihrem Enum-with-Konstruktor rasieren, indem Sie das
name
Feld deklarierenpublic final
und den Getter verlieren. (Was ist diese Liebe, die Java-Programmierer zu Gettern haben?)quelle
public final static int white = 1;
oderpublic final static String white = "white";
(abgesehen von einem erneuten Verstoß gegen die Konvention), verliert dies die Typensicherheit, die die Aufzählung bietet.public final
Instanzfeld, das vom Konstruktor initialisiert wird, verhält sich genau wie ein nicht endgültiges Feld, außer dass Sie beim Kompilieren daran gehindert werden , es zuzuweisen. Sie können es über Reflection ändern, und der gesamte Code, der darauf verweist, zeigt sofort den neuen Wert an.Das Befolgen der UPPERCASE-Namenskonvention verstößt möglicherweise gegen DRY . (Und YAGNI ). Beispiel: In Ihrem Codebeispiel 2 werden "ROT" und "Rot" wiederholt.
Befolgen Sie also die offizielle Konvention oder DRY? Ihr Anruf.
In meinem Code werde ich DRY folgen. Ich werde jedoch einen Kommentar zur Enum-Klasse abgeben und sagen: "Nicht alle Großbuchstaben, weil (Erklärung hier)"
quelle