Seit Java 1.7 können Strings mit switch-Anweisungen verwendet werden, was mich etwas beunruhigt. switch
Anweisungen auf Integer-Werte in Sprungtabellen umgewandelt werden, die schneller sind als einfach if
prüft auf Ganzzahlen berechnet zur Laufzeit; Kann eine ähnliche Optimierung mit Strings durchgeführt werden oder ist dies nur syntaktischer Zucker?Ist Switch mit Strings mehr als nur syntaktischer Zucker?
Antwort
Yes Schalter mit Schnur ist ein syntatic Zucker. Von here
1) Strings in Switch sind syntaktischer Zucker, keine Änderung der JVM-Ebene.
2) Intern verwendet es equals-Methode zu vergleichen, das heißt, wenn Sie übergeben Null wird es werfen java.lang.NullPointerException, also Vorsicht vor dass.
3) Bei Strings in Switch-Anweisungen wird zwischen Groß- und Kleinschreibung unterschieden, vorzugsweise wird nur ein Fall verwendet und die Eingabe in den bevorzugten Fall konvertiert, bevor sie an switch statement übergeben wird.
Überprüfen Sie auch How String in Switch works in Java 7
Aus dem gleichen Link, wenn Sie das Beispiel sehen:
public class StringInSwitchCase{
public static void main(String[] args) {
String mode = args[0]; switch (mode) {
case "ACTIVE": System.out.println("Application is running on Active mode");
break;
case "PASSIVE": System.out.println("Application is running on Passive mode");
break;
case "SAFE": System.out.println("Application is running on Safe mode");
} } }
und den dekompilierten Code:
import java.io.PrintStream;
public class StringInSwitchCase{
public StringInSwitchCase() { }
public static void main(string args[]) {
String mode = args[0]; String s;
switch ((s = mode).hashCode()) {
default: break;
case -74056953: if (s.equals("PASSIVE")) {
System.out.println("Application is running on Passive mode"); }
break;
case 2537357: if (s.equals("SAFE")) { System.out.println("Application is running on Safe mode"); }
break;
case 1925346054: if (s.equals("ACTIVE")) { System.out.println("Application is running on Active mode"); }
break; } } }
werden Sie feststellen, dass String in Switch funktioniert mit hashCode()
und equals()
Methode.
Wie erwartet verwendet es hashCode() Methode zum Schalten und equals() Verfahren zur Verifikation bedeutet dies, es ist nur ein syntaktischer Zucker, anstatt eine eingebaute nativen Funktionalität.
Die letzten beiden Aussagen dort treffen mich als widersprüchlich: ist der Unterschied in der Byte-Code-Effizienz wirklich so groß, wenn es erfordert, dass Sie eine neue, niedrigere/erstellen Großbuchstaben, um es zu benutzen? –
Also ... wenn der Byte-Code effizienter ist, dann sind sie nicht genau syntaktischer Zucker. – RealSkeptic
@JeroenVannevel: - Ja das ist widersprüchlich. Ich habe diesen Teil entfernt und den Code hinzugefügt, um ihn klarer zu machen. –
Der Compiler optimiert eine switch
Anweisung basierend auf String-Werte der hashCode()
Methode verwenden, und verwendet dann eine Lookup-Tabelle im Bytecode. Dies ist im Allgemeinen effizienter als eine if
- else
Anweisung.
Zum Beispiel die folgenden:
String string = "x";
switch(string) {
case "x": System.out.println("x");
break;
case "y": System.out.println("y");
break;
case "z": System.out.println("z");
break;
}
ist diesem Bytecode umgewandelt:
ldc "x"
astore_1
aload_1
astore_2
iconst_m1
istore_3
aload_2
invokevirtual java/lang/String/hashCode()I
tableswitch 120
10
17
24
default: 30
aload_2
ldc "x"
invokevirtual java/lang/String/equals(Ljava/lang/Object;)Z
ifeq 30
iconst_0
istore_3
goto 30
aload_2
ldc "y"
invokevirtual java/lang/String/equals(Ljava/lang/Object;)Z
ifeq 30
iconst_1
istore_3
goto 30
aload_2
ldc "z"
invokevirtual java/lang/String/equals(Ljava/lang/Object;)Z
ifeq 30
iconst_2
istore_3
iload_3
tableswitch 0
32
36
40
default: 43
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc "x"
invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
goto 43
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc "y"
invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
goto 43
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc "z"
invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
return
Warum wäre das effizienter? Ein Einschalten von im Wesentlichen zufälligen Schlüsseln kann keine Sprungtabelle verwenden. Die Sprungtabelle würde im schlimmsten Fall 2^32 Einträge benötigen. – usr
@ usr Auch wenn eine Jump-Tabelle nicht verwendet werden kann, selbst wenn der Switch eine Reihe von if-else-Prüfungen für einen Integer-Wert beendet, ist dies immer noch weniger teuer als eine Reihe von if-else-Prüfungen für einen String-Wert. – hvd
- 1. ist begin..end in OCaml syntaktischer Zucker?
- 2. Scala Map: geheimnisvoller syntaktischer Zucker?
- 3. Rubin syntaktischer Zucker: Umgang mit nils
- 4. QT Eigenschaften - syntaktischer Zucker oder Entwicklungstools
- 5. Scala's For-Comprehensions: Vitalfunktion oder syntaktischer Zucker?
- 6. Kürzel für for-Schleife - syntaktischer Zucker in C++ (11)
- 7. Scala syntaktischer Zucker für die Umwandlung zu `Option`
- 8. Funktionen höherer Ordnung in C als syntaktischer Zucker mit minimalem Aufwand
- 9. wie man const function javascript (syntaktischer Zucker) definiert?
- 10. Syntactic Zucker vs Feature
- 11. Gibt es einen Anwendungsfall für std :: function, der nicht von Funktionszeigern abgedeckt wird, oder ist es nur syntaktischer Zucker?
- 12. Ersetzen Strings, die mehr als einmal
- 13. Pfsense als Router mit Switch
- 14. Ist "else if" schneller als "switch() case"?
- 15. Schwieriger boo syntaktischer Makro
- 16. Wo ist `+` für Strings im Java-Quellcode implementiert?
- 17. Switch Gehäuse als String
- 18. Sprachen mit nativer/syntaktischer/Inline-Graph-Unterstützung?
- 19. int.TryParse syntaktischen Zucker
- 20. Welches ist der beste Weg, mehr als ein Strings in der gleichen Methode in C#
- 21. Syntax Zucker: _ * für Seq als Methode der Behandlung Parameter
- 22. ist der Operator "ist" nur syntaktische Zucker für die "IsInstanceOfType" -Methode
- 23. Die Projektionsmatrix ist mehr als skalieren, oder?
- 24. NModbus4 startAddress ist mehr als ushort kann
- 25. Gesprochene Strings mit nur Kleinbuchstaben suchen?
- 26. Operatoren als Strings
- 27. Strings im Array sind keine Strings mehr nach jQuery.each()
- 28. IOCTL: arbeite nur mit Parameter 0 im Switch-Case
- 29. Return-Array mit den längsten Strings nur
- 30. pyyaml und mit Anführungszeichen für Strings nur
'String' Schalter scheint eine feste Größe Karte implementiert werden unter Verwendung von in der logarithmischen Leistung führt für eine kleine Anzahl von Artikel. Siehe http://java-performance.info/string-switch-performance/ – isnot2bad