java - 带字符串的 switch 不仅仅是语法糖吗?

标签 java string switch-statement

<分区>

从 Java 1.7 开始,字符串可以与 switch 语句一起使用,这让我想知道一些事情。整数值的 switch 语句被转换为跳转表,这比简单地对运行时计算的整数进行 if 检查更快;可以对字符串进行类似的优化吗?还是这只是语法糖?

最佳答案

编译器使用hashCode() 方法根据字符串值优化switch 语句,然后在字节码中使用查找表。这通常比 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

关于java - 带字符串的 switch 不仅仅是语法糖吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29721701/

相关文章:

java - 用逗号分割字符串并忽略双引号中的逗号

C语言: Switch cases weird example not ending with ";" nor "break"

c# - 嵌套开关?或其他检查不同条件的解决方案?

java - Spring JPA hibernate : slow SELECT query

Python - 在使用正则表达式查找句点(句号或 .)时,我应该使用字符串前缀 r 吗?

java - 常量实用程序类中的最终关键字

c - 将 unsigned long 转换为字符串的缓冲区大小

php switch case语句来处理范围

java - com.mysql.cj.jdbc.exceptions.CommunicationsException : The last packet successfully received from the server was XXXXXXXXXXXX milliseconds ago

Java FileInputStream 问题(额外空格)