从Java 1.7开始,字符串可以与switch语句一起使用,这让我有些疑惑。关于整数值的switch
语句可以转换为跳转表,这比简单地对运行时计算的整数进行if
检查要快;可以用字符串进行类似的优化,还是仅仅是语法糖?
答案 0 :(得分:7)
编译器使用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
答案 1 :(得分:6)
是的,带字符串的开关是一种合成糖。来自here
1)Switch中的字符串是语法糖,JVM级别没有变化。
2)在内部,它使用equals方法进行比较,这意味着,如果你 传递null它会抛出java.lang.NullPointerException,所以要小心 这一点。
3)switch语句中的字符串区分大小写,更喜欢只使用 一个案例并在将输入转换为首选案例之前将其转换为 切换声明。
同时检查 How String in Switch works in 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; } } }
你会发现Switch中的String可以使用hashCode()
和equals()
方法。
正如预期的那样,它使用hashCode()方法进行切换和equals() 验证方法,这意味着它只是一种语法糖, 而不是内置的本机功能。