自Java 1.7以来,字符串可以与switch语句一起使用,这让我想到了一些东西。 switch
将整数值的语句转换为跳转表,这比仅对if
检查运行时计算的整数更快;可以用字符串进行类似的优化,还是仅仅是语法糖?切换字符串不仅仅是语法糖吗?
回答
是的字符串切换是一种合成糖。 From here
1)Switch中的字符串是语法糖,JVM级别没有变化。
2)它在内部使用equals方法进行比较,也就是说,如果你传递null,它会抛出java.lang.NullPointerException,所以要当心 那个。
3)switch语句中的字符串区分大小写,倾向于只使用 一种情况,并在将输入传递给 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中使用hashCode()
和equals()
方法。
如所预期的,它使用的hashCode()方法用于切换和equals()方法用于验证 方法,这意味着它只是一个语法糖, 而不是一个内置的本地功能。
最后两条语句让我感到矛盾:字节码效率的差异真的很大,如果它需要您创建新的较低/大写字母为了使用它? –
所以......如果字节码更高效,那么它们不完全是语法糖。 – RealSkeptic
@JeroenVannevel: - 这是矛盾的。我删除了该部分并添加了代码以使其更加清晰。 –
编译器优化基于使用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
- 1. Groovy String表达式不仅仅是语法糖吗?
- 2. LINQ循环实际上更快还是仅仅是语法糖?
- 3. 是 “””为原始字符串语法糖
- 4. Java String.replace() - 替换的不仅仅是我指定的子字符串吗?
- 5. 计算字符串中的字数(不仅是拉丁语言)
- 6. 字符串切换语句
- 7. 是build_语法糖吗?
- 8. 将字符串语句转换为切换字符串语句
- 9. 确定字符串的实际长度不仅仅是字符数
- 10. For循环中的整个字符串,而不仅仅是字符
- 11. 仅转换日期到字符串
- 12. 仅替换字符串的末尾
- 13. C#按字符串拆分[]分隔符仅匹配确切字
- 14. AngularJS对待POST响应作为字符串数组,而不是仅仅串
- 15. 仅在外部字符串中替换C#字符串
- 16. .write(string)用新字符串替换所有文件,还是仅仅追加它?
- 17. Python的CSV模块分割字符串,而不仅仅是字段
- 18. 删除字符串,如果它仅仅是最后一部分
- 19. @Produces @Consumes意义...... JSON或者它仅仅是一个字符串
- 20. 如何将C#资源文件字符串转换为方法而不仅仅是属性?
- 21. dup2不仅仅是复制文件描述符吗?
- 22. 服务定位符不仅仅是全局变量/状态吗?
- 23. PHP字符串仅控制
- 24. 仅提取从字符串
- 25. QInputDialog不返回不仅仅是文字
- 26. 用字符串切换语句?
- 27. 切换3个类onclick(仅切换2)
- 28. 验证字符串 - 仅限特定语言字符
- 29. 链接不仅仅是文字,对SEO有用吗?
- 30. Redux形式的字段值可以容纳对象而不仅仅是一个字符串吗?
'String'开关似乎使用固定大小的地图导致对于小数目的对数的性能来实现项目。请参阅http://java-performance.info/string-switch-performance/ – isnot2bad