Als ich anfing, in Java zu programmieren, frustrierte mich die Tatsache, dass switch-Anweisungen keine Zeichenketten enthielten. Bei der Verwendung von Enums erkannte ich die Vorteile, die Sie mit ihnen erzielen, anstatt Rohwerte weiterzugeben - Typensicherheit (die das Refactoring vereinfacht) und Klarheit für andere Entwickler.
Ich habe Mühe, mir eine Situation vorzustellen, in der ich mit SE7 jetzt einen Schalter mit Zeichenfolgen als Eingaben anstelle von Enums verwende. Wenn sie durch Einschalten ganzer Zeichenfolgen implementiert werden (z. B. anstelle von Teil- oder Regex-Übereinstimmungen), bietet dies anscheinend keinen geringeren Grund für eine Änderung des Codes.
Und mit IDE-Tools und dem Lese- / Schreibverhältnis der Codierung wäre es viel glücklicher, eine zusätzliche Enumeration zu generieren, als Zeichenfolgenwerte weiterzugeben.
Welchen Nutzen bringen sie uns als Programmierer? Weniger Kesselplatte?
Es fühlt sich nicht so an, als würde die Sprache nach dieser Funktion schreien. Obwohl ich vielleicht einen Anwendungsfall übersehen habe.
quelle
Antworten:
Soweit ich das beurteilen kann, stellt sich die Frage, warum das Einschließen von String-Konstanten in Enum nicht ausreicht, um die Bedürfnisse der Sprachbenutzer abzudecken. Dies wurde in dem offiziellen Feature-Vorschlag behoben, der auf der JDK 7-Mailingliste (Project Coin) angekündigt wurde.
Nach meiner Lektüre des Vorschlags wurde die Alternative der Verwendung von Aufzählungen mit der Begründung verworfen, dass es Typen aufbläht. Der Einfachheit halber wird der relevante Teil des Vorschlags im Folgenden mit fettgedruckten Anweisungsadressen angegeben :
quelle
Abgesehen davon, dass der Code besser lesbar ist, ergeben sich potenzielle Leistungssteigerungen im
if/else if
Vergleich zu Vergleichen. Ob sich die Änderung lohnt, hängt davon ab, wie viele Vergleiche Sie durchführen würden. Ein String-Schalter wird als zwei separate Schalterbefehle ausgegeben. Die erste arbeitet auf Hash - Codes, so dass es eine tendenziell zulookupswitch
, wodurch man letztendlichO(log n)
Komplexität. Der zweite ist immer perfektO(1)
tableswitch
, daher ist die kombinierte Komplexität immer noch vorhandenO(log n)
. Eine einzelne lineareif/else if
Anweisungskette würde dieO(n)
Komplexität etwas verschlechtern .Wenn Sie mehr als beispielsweise drei Zeichenfolgen vergleichen,
switch
ist a wahrscheinlich lesbarer und kompakter. Die Leistung ist wahrscheinlich besser, obwohl Sie kaum einen Unterschied bemerken, es sei denn, Sie führen eine große Anzahl von Vergleichen auf einem Hot-Code-Pfad durch.quelle
if/else
Block-Bad-Practice in Betracht ziehen , aber im Moment hätte ich nicht viel Grund, ein solches zu verwenden.Der Schalter für Zeichenfolgen kann verwendet werden, wenn Ihre
enum
Werte von außerhalb kommen, dh in einer Datenbank gespeichert sind.Eine andere bemerkenswerte Sache in JDK 7
switch
ist, dass es viel leistungsfähiger ist alsif-else
Konstrukte.Ein nützlicher Anwendungsfall für schnelle Zeichenfolgen ist das
switch
Analysieren von JSON / XML-Streams, wenn Sie zahlreiche Optionen für Knoten- und Attributtypen festlegen müssen. Ich kann mir keine bessere Option dafür vorstellen.quelle
enum
s kann in diesem Fall aufgrund der statischen Natur von Java verwendet werden. Als ich dies schrieb, dachte ich über eineRole
Sicherheitsbibliothek nach, die in der Regel als Klasse bereitgestellt wird und nicht abgelegt werden kannenum
. Ein anderer Fall ist ein dynamisch kompilierter Java / Groovy-Code - in dieser Situation, die jedoch selten vorkommt, sind String-Schalter möglicherweise die bessere Option.Einfachheit
String in Switch-Unterstützung ist nützlich für die Verarbeitung von Daten ohne Konvertierung in Enum oder
if-else
Logik. Manchmal ist es einfach einfacher, String einzuschalten.Aus dem Funktionsvorschlag der JDK 7-Mailingliste (Project Coin) ( @gnat answer )
If-Else-Version
Dies ist kurz, aber viele
if's
sind schwer zu lesen. Und das ist langsam.Enum-Version
Aufzählungen müssen definiert werden, das ist gut, wird aber manchmal nicht benötigt.
Verarbeitung wie gewohnt
JDK 7 - Strings in switch-Statements-Version
Wir können verarbeiten, ohne zusätzliche Typen zu konvertieren und zu definieren.
quelle
Die meisten Verbesserungen in einer Sprache bestehen darin, den Code besser lesbar zu machen. Ich bevorzuge jeden Tag lesbaren Code.
Sie können dies nicht glauben, aber versuchen Sie:
quelle
Enums sind großartig und Sie sollten diese anstelle von Strings verwenden, wenn Sie dazu in der Lage sind. Es gibt jedoch Situationen, in denen dies nicht möglich ist, beispielsweise wenn Sie mit externen Objekten von außerhalb von Java arbeiten müssen. Stellen Sie sich vor, Sie müssen etwas analysieren. Wie Serverantwort, Konfiguration, Protokolldatei oder ähnliches: Sie haben eine Reihe von Optionen, nach denen Sie suchen, und es gibt keine Möglichkeit, dass diese Aufzählungen sein könnten. In Java <7 steckst du also fest
Sie können in diesem Fall weiterhin Aufzählungen verwenden, indem Sie nur versuchen, diese nach Namen abzurufen, und / oder indem Sie eine benutzerdefinierte String-> Enum-Routine bereitstellen. Manchmal ist dies jedoch nicht möglich oder einfach nicht praktikabel (dh, wenn Sie zu viele Aufzählungen erstellen müssten).
TLDR : Sie sollten unbedingt Enums verwenden, wenn Sie ausschließlich mit Java-Code arbeiten, dies ist jedoch nicht immer mit externen Objekten möglich. Ich hoffe meine Erklärung macht Sinn.
quelle
if
Anweisungen benötigen , sollten Sie sie trotzdem einpacken , was bedeutet, dass Sie weiterhin Aufzählungen oder ein Befehlsmuster usw. verwenden könnenIch bin nicht der Meinung, dass es sauberer und lesbarer Code ist, wenn Sie
Strings
in switch-Anweisungen verwenden, und denke, dass es eine schlechte Programmierpraxis ist. Wenn Sie den Wert ändern, den Sie zum Speichern verwenden, müssen Sie ihn bei jedem Switch oder if-elseif-Vorkommen ändern. Dies ist nicht gut, da Sie jedem Teil Ihres Codes fest codierte Werte zuweisen. Was machen Sie, wenn Sie eines Tages einen dieser hartcodierten Werte ändern? Suchen und ersetzen Sie jede Kopie davon?Wenn Sie einige hartcodierte Werte haben, die Sie mit if-elseif-Anweisungen ausführen, ist die Verwendung von konstanten Grundwerten vor Java 1.5 viel besser, nur weil dies die Typensicherheit erhöht.
OK, es wird Situationen geben, in denen Sie Zeichenfolgenwerte erhalten (von HTTP-Anforderungen, Dateien usw.), und die Konvertierung in die primitiven Werte ist sehr schmerzhaft. Aber
Enum
an diesem Punkt machen wir einen guten Job. Wenn Sie den in Enum gespeicherten Wert ändern möchten, müssen Sie ihn nur bei der Deklaration ändern. An Ihrem Code müssen keine weiteren Änderungen vorgenommen werden. (Sie müssen natürlich die Werte ändern, die woanders gespeichert sind).Natürlich ist es perfekt, wenn Sie nur einen schmutzigen und faulen Code implementieren. Sie möchten nicht viele
Enum
s programmieren , sondern komplexe Software in großem Maßstab, die Sie umbringen wird.quelle
Wenn Sie wissen, welche Informationen eingehen und dass es sich nur um 5 Zustände handeln kann, verwenden Sie ein
Enum
. Wenn die möglichen Zustände jedoch über 9000 liegen und Sie nur 42 finden müssen, ist es besser, einen Schalter zu verwenden, da Sie nicht alle diese Zustände ausschreiben möchten.In den meisten Fällen ist eine Aufzählung die beste Wahl, es sei denn, die möglichen Zustände sind unbekannt oder es gibt viele, und Sie kümmern sich nur um wenige.
Aber warum haben sie es jetzt eingeführt? Es war nur eine Änderung, die saubereren Code ermöglichte.
In Version 1.5 konnten Sie auch benutzerdefinierte Körper für Enums erstellen.
quelle
default
inswitch
um Spiel kommt. Ich weiß nicht, dass Sie einen Standardzustand mit haben könnenEnum
, es sei denn, Sie machen einen Standardzustand, aber dann wird dieser Code nur aufgebläht, während aswitch
viel sauberer zu verwenden ist.UNKNOWN
Zustand auf einem Enum aufgedunsen ist, eindefault
Fall auf einem Switch jedoch nicht.