Wird diese Funktion in einer späteren Java-Version enthalten sein?
Kann mir jemand erklären, warum ich das nicht tun kann, d.h. die technische Art und Weise, wie Java's switch
Aussage funktioniert?
Wird diese Funktion in einer späteren Java-Version enthalten sein?
Kann mir jemand erklären, warum ich das nicht tun kann, d.h. die technische Art und Weise, wie Java's switch
Aussage funktioniert?
Switch-Anweisungen mit String
Fälle wurden umgesetzt in Java SE 7 , mindestens 16 Jahre nachdem sie zum ersten Mal angefordert wurden. Ein klarer Grund für die Verzögerung wurde nicht genannt, aber er hatte wahrscheinlich mit der Leistung zu tun.
Die Funktion wurde jetzt in folgende Bereiche implementiert javac
mit einem "De-Sugaring"-Prozess; eine saubere, hochsprachliche Syntax mit String
Konstanten in case
Deklarationen zur Kompilierzeit zu komplexerem Code nach einem Muster erweitert wird. Der resultierende Code verwendet JVM-Anweisungen, die schon immer existierten.
A switch
avec String
Fälle werden bei der Kompilierung in zwei Schalter übersetzt. Der erste ordnet jede Zeichenfolge einer eindeutigen Ganzzahl zu - ihrer Position im ursprünglichen Schalter. Dies geschieht, indem zunächst der Hash-Code des Labels eingeschaltet wird. Der entsprechende Fall ist ein if
Anweisung, die die Gleichheit von Zeichenketten prüft; wenn es Kollisionen auf dem Hash gibt, ist der Test eine kaskadierende if-else-if
. Der zweite Schalter spiegelt den des ursprünglichen Quellcodes wider, ersetzt aber die Groß-/Kleinschreibung durch die entsprechenden Positionen. Dieser zweistufige Prozess macht es einfach, die Flusskontrolle des ursprünglichen Schalters zu erhalten.
Für mehr technische Tiefe über switch
können Sie in der JVM-Spezifikation nachschlagen, wo die Zusammenstellung von switch-Anweisungen beschrieben wird. Kurz gesagt gibt es zwei verschiedene JVM-Befehle, die für einen Schalter verwendet werden können, je nach der Sparsamkeit der von den Fällen verwendeten Konstanten. Beide hängen von der Verwendung ganzzahliger Konstanten für jeden Fall ab, um effizient ausgeführt werden zu können.
Wenn die Konstanten dicht sind, werden sie als Index (nach Abzug des niedrigsten Wertes) in einer Tabelle mit Anweisungszeigern verwendet - der tableswitch
Anweisung.
Wenn die Konstanten spärlich sind, wird eine binäre Suche nach dem richtigen Fall durchgeführt - die lookupswitch
Anweisung.
Bei der Entzuckerung eines switch
auf String
Objekten, werden wahrscheinlich beide Anweisungen verwendet. Die Website lookupswitch
eignet sich für den ersten Schalter auf Hash-Codes, um die ursprüngliche Position des Gehäuses zu finden. Die sich daraus ergebende Ordnungszahl ist eine natürliche Passform für eine tableswitch
.
Bei beiden Anweisungen müssen die jedem Fall zugewiesenen Ganzzahlkonstanten zur Kompilierzeit sortiert werden. Zur Laufzeit, während die O(1)
Leistung von tableswitch
erscheint im Allgemeinen besser als die O(log(n))
Leistung von lookupswitch
Wenn die Tabelle so dicht ist, dass der Zeit- und Raumaufwand gerechtfertigt ist, muss eine Analyse durchgeführt werden. Bill Venners schrieb ein großartiger Artikel in dem dies ausführlicher behandelt wird, zusammen mit einem Blick unter die Haube auf andere Java-Flusssteuerungsanweisungen.
Vor JDK 7, enum
könnte eine Annäherung an eine String
-basierten Schalter. Dieser verwendet die Statik valueOf
Methode, die vom Compiler bei jeder enum
Art. Zum Beispiel:
Pill p = Pill.valueOf(str);
switch(p) {
case RED: pop(); break;
case BLUE: push(); break;
}
Wenn Sie eine Stelle in Ihrem Code haben, an der Sie eine Zeichenkette einschalten können, dann ist es vielleicht besser, die Zeichenkette zu einer Aufzählung der möglichen Werte umzuformulieren, die Sie einschalten können. Natürlich schränken Sie die möglichen Werte von Strings auf die in der Aufzählung enthaltenen ein, was erwünscht sein kann oder auch nicht.
Natürlich könnte Ihre Aufzählung einen Eintrag für "other" und eine fromString(String)-Methode haben, dann könnten Sie
ValueEnum enumval = ValueEnum.fromString(myString);
switch (enumval) {
case MILK: lap(); break;
case WATER: sip(); break;
case BEER: quaff(); break;
case OTHER:
default: dance(); break;
}
Im Folgenden finden Sie ein vollständiges Beispiel, das auf dem Beitrag von JeeBee basiert, wobei Java Enum's anstelle einer benutzerdefinierten Methode verwendet werden.
Beachten Sie, dass Sie in Java SE 7 und höher stattdessen ein String-Objekt im Ausdruck der switch-Anweisung verwenden können.
public class Main {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
String current = args[0];
Days currentDay = Days.valueOf(current.toUpperCase());
switch (currentDay) {
case MONDAY:
case TUESDAY:
case WEDNESDAY:
System.out.println("boring");
break;
case THURSDAY:
System.out.println("getting better");
case FRIDAY:
case SATURDAY:
case SUNDAY:
System.out.println("much better");
break;
}
}
public enum Days {
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY,
SUNDAY
}
}
Schalter, die auf Ganzzahlen basieren, können zu sehr effizientem Code optimiert werden. Schalter, die auf anderen Datentypen basieren, können nur in einer Reihe von if()-Anweisungen kompiliert werden.
Aus diesem Grund sind in C und C++ nur Schalter für Integer-Typen zulässig, da dies bei anderen Typen sinnlos ist.
Die Entwickler von C# haben entschieden, dass der Stil wichtig ist, auch wenn er keine Vorteile bringt.
Die Entwickler von Java dachten offenbar wie die Entwickler von C.
Ein Beispiel für direkte String
Die Nutzung seit 1.7 kann ebenfalls angezeigt werden:
public static void main(String[] args) {
switch (args[0]) {
case "Monday":
case "Tuesday":
case "Wednesday":
System.out.println("boring");
break;
case "Thursday":
System.out.println("getting better");
case "Friday":
case "Saturday":
case "Sunday":
System.out.println("much better");
break;
}
}
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
203 Stimmen
Es ist in SE 7. 16 Jahre nach seinem Antrag. download.oracle.com/javase/tutorial/java/nutsandbolts/
88 Stimmen
Sun war ehrlich in ihrer Bewertung:
"Don't hold your breath."
lol, bugs.sun.com/bugdatabase/view_bug.do?bug_id=12231793 Stimmen
@raffian Ich glaube, das liegt daran, dass sie zweimal 'seufzte'. Sie waren auch ein bisschen spät dran mit ihrer Antwort, nach fast 10 Jahren. Vielleicht hat sie damals Lunchpakete für ihre Enkelkinder gepackt.