Так как Java 1.7, строки могут использоваться с операторами switch, что заставляет меня задуматься. Операторы switch
для целочисленных значений превращаются в таблицы перехода, которые быстрее, чем просто выполнение if
проверок целых чисел, вычисляемых во время выполнения; может ли подобная оптимизация быть выполнена со строками или это просто синтаксический сахар?
Является ли переключатель со строками больше, чем просто синтаксическим сахаром?
Ответ 1
Да, переключатель со строкой - это синтаксический сахар. Из здесь
1) Строки в Switch - это синтаксический сахар, без изменения уровня JVM.
2) Внутри он использует метод equals для сравнения, что означает, если вы передать null, он будет вызывать java.lang.NullPointerException, поэтому остерегайтесь что.
3) Строки в операторах switch чувствительны к регистру, предпочитают использовать только один случай и преобразовать ввод в предпочтительный случай, прежде чем передавать их switch.
Также проверьте Как работает String в Switch в Java 7
Из той же ссылки, если вы видите пример:
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");
} } }
и декомпилированный код:
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; } } }
вы узнаете, что String в Switch работает с помощью методов hashCode()
и equals()
.
Как и ожидалось, он использует метод hashCode() для переключения и equals() метод проверки, это означает, что это просто синтаксический сахар, а не встроенные встроенные функции.
Ответ 2
Компилятор оптимизирует оператор switch
на основе строковых значений, используя метод hashCode()
, а затем использует таблицу поиска в байте-коде. Это обычно более эффективно, чем оператор if
- else
.
Например, следующее:
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;
}
преобразуется в этот байт-код:
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