switch语句中的String如何比相应的if-else语句更有效?

Java文档说

Java编译器通过使用String对象的switch语句而不是链式的if-then-else语句生成通常更有效的字节码。

AFAIK甚至string切换使用.equals()在内部以区分大小写的方式。 那么在这种情况下他们的含义是什么? 编译速度更快? less了字节码? 更好的性能?

使用switch语句比equals语句更快(但只有当有多个string时才显着),因为它首先使用打开的string的hashCode来确定可能匹配的string的子集。 如果case标签中的多个string具有相同的hashCode,则JVM将执行对equals连续调用,即使在case标签中只有一个string是一个hashCode,JVM需要调用equals来确认string在case标签真的等于switchexpression式中的标签。

String对象上的开关的运行时性能与HashMap的查找相当。

这段代码:

 public static void main(String[] args) { String s = "Bar"; switch (s) { case "Foo": System.out.println("Foo match"); break; case "Bar": System.out.println("Bar match"); break; } } 

内部编译并像这样的代码执行:

(不是字面意思,但是如果你反编译这两个代码片段,你会发现完全相同的动作序列)

 final static int FOO_HASHCODE = 70822; // "Foo".hashCode(); final static int BAR_HASHCODE = 66547; // "Bar".hashCode(); public static void main(String[] args) { String s = "Bar"; switch (s.hashCode()) { case FOO_HASHCODE: if (s.equals("Foo")) System.out.println("Foo match"); break; case BAR_HASHCODE: if (s.equals("Bar")) System.out.println("Bar match"); break; } } 

一般来说 ,switch语句更好,因为它们(松散地说)是O(1) ,而if-else的链是O(n)

n条件可能导致多达n比较使用链接的if-else语句。

switch语句可以直接跳转到适当的条件(如地图)或默认情况下,使其成为O(1)

这是从文档中的示例生成的字节码片段:

  INVOKEVIRTUAL java/lang/String.hashCode ()I LOOKUPSWITCH -2049557543: L2 -1984635600: L3 -1807319568: L4 

与if-else逻辑相比,使用LOOKUPSWITCH具有更好的性能