为什么switch语句比Java 7中的String更快? [英] Why is the switch statement faster than if else for String in Java 7?
问题描述
在 Java 7 中,字符串
对象可以在开关
的表达式中声明。有人可以从官方文档<解释以下声明/ a>?
In Java 7 a string
object can be in the expression of a switch
statement. Can someone explain the below statement from official documentation?
Java编译器通常使用字符串对象的switch语句生成更高效的字节码链接if-then-else语句。
The Java compiler generates generally more efficient bytecode from switch statements that use String objects than from chained if-then-else statements.
推荐答案
Java代码
有两个版本的类,例如
Java Code
Having two versions of a class, e.g.
使用 if-then-else
:
public class IfThenElseClass {
public static void main(String[] args) {
String str = "C";
if ("A".equals(str)) {
} else if ("B".equals(str)) {
} else if ("C".equals(str)) {
}
}
}
使用开关
:
public class SwitchClass {
public static void main(String[] args) {
String str = "C";
switch (str) {
case "A":
break;
case "B":
break;
case "C":
break;
}
}
}
字节码
让我们来看看字节码。获取的字节码if-then-else
版本:
Compiled from "CompileSwitch.java"
public class CompileSwitch {
public CompileSwitch();
Code:
0: aload_0
1: invokespecial #8 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: ldc #16 // String C
2: astore_1
3: ldc #18 // String A
5: aload_1
6: invokevirtual #20 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
9: ifne 28
12: ldc #26 // String B
14: aload_1
15: invokevirtual #20 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
18: ifne 28
21: ldc #16 // String C
23: aload_1
24: invokevirtual #20 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
27: pop
28: return
}
获取开关的字节码
版本:
Compiled from "CompileSwitch.java"
public class CompileSwitch {
public CompileSwitch();
Code:
0: aload_0
1: invokespecial #8 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: ldc #16 // String C
2: astore_1
3: aload_1
4: dup
5: astore_2
6: invokevirtual #18 // Method java/lang/String.hashCode:()I
9: lookupswitch { // 3
65: 44
66: 56
67: 68
default: 77
}
44: aload_2
45: ldc #24 // String A
47: invokevirtual #26 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
50: ifne 77
53: goto 77
56: aload_2
57: ldc #30 // String B
59: invokevirtual #26 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
62: ifne 77
65: goto 77
68: aload_2
69: ldc #16 // String C
71: invokevirtual #26 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
74: ifne 77
77: return
}
结论
-
在第一个版本中,通过调用
等于
每个条件的方法,直到找到它。Conclusion
In the first version compares the string by calling the
equals
method for each condition, until it is found.在第二个版本中首先获得
hashCode
的字符串。然后将其与值hashCode
每个case
进行比较。请参阅lookupswitch
。如果重复这些值中的任何一个,则恰好运行case
的代码。否则,请调用绑定案例的等于
方法。这比以前更快地调用等于
方法。In the second version is obtained first
hashCode
of the string. Then this is compared with the values hashCode
eachcase
. See thelookupswitch
. If any of these values is repeated just happens to run the code for thecase
. Otherwise, call theequals
method of the cases tied. This is much faster than ever call theequals
method only.这篇关于为什么switch语句比Java 7中的String更快?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!