Java的交换机是如何工作的?

Java的switch语句如何在幕后工作? 它如何比较正在使用的变量的值与案例部分中给出的值? 它是使用==.equals() ,还是完全不同的东西?

我主要对前1.7版本感兴趣。

都不是。 它使用lookupswitch JVM指令,它本质上是一个表查找。 看一下以下示例的字节码:

 public static void main(String... args) { switch (1) { case 1: break; case 2: break; } } public static void main(java.lang.String[]); Code: Stack=1, Locals=1, Args_size=1 0: iconst_1 1: lookupswitch{ //2 1: 28; 2: 31; default: 31 } 28: goto 31 31: return 

从这个答案可以看出,Java switch (至少在1.7之前)并不总是编译成== .equals() 。 相反,它使用表查找。 虽然这是一个非常小的微优化,但在进行大量的比较时,表查找几乎总是更快。

请注意,这仅用于检查密集密钥的switch语句。 例如,检查枚举值的所有可能性可能会产生这种主要实现(内部称为tableswitch )。

如果检查更多稀疏填充的密钥集,JVM将使用替代系统,称为lookupswitch 。 它将简单地比较各种键和值,基本上对每种可能性进行优化的==比较。 为了说明这两种方法,请考虑以下两个switch语句:

 switch (value1) { case 0: a(); break; case 1: b(); break; case 2: c(); break; case 3: d() break; } switch (value2) { case 0: a(); break; case 35: b(); break; case 103: c(); break; case 1001: d(); break; } 

第一个例子很可能使用表查找,而另一个例子(基本上)使用==比较。

从这里复制

在字节码中有两种forms的开关:tableswitch和lookupswitch。 一个假设密集的密钥,另一个密集。 请参阅JVM规范中的编译开关说明。 对于枚举,找到序号,然后代码继续作为int情况。 我不完全确定如何实现JDK7中建议的字符串小function的开关。

但是,大量使用的代码通常在任何合理的JVM中编译。 优化者并非完全愚蠢。 不要担心,并按照通常的启发式方法进行优化。

你会在这里找到详细的答案

1.Java 7到来之前,它是"==" ,因为我们可以使用整数和char作为switch case,因为它们是原始的 ,所以它必须是"=="

2.Java 7在switch case中也允许使用 String,而String是一个object ,使用".equals"

我想补充一点…… "=="用于比较 Object Reference Variable而不是对象本身 。 使用".equals"我们比较对象

如果使用pre 1.7 Java,我认为它使用

==

因为对于int,你不能做例如等于enum,equals和==将返回相同

编辑

我的假设是错误的它使用了一个查找表,在字节码中它想像:

  tableswitch 

这比普通的if / else快得多,正如其他人所指出的那样。

如果你使用原始类型,比如整数,那么java将使用==来比较它们如果你使用的是字符串,那么java将使用equals()方法来测试字符串是否相等。 如果你使用带枚举的switch语句,那么==equals()都是相同的,所以使用哪一个并不重要。

交换机使用byte,short,char和int原始数据类型。 它还适用于枚举类型(在枚举类型中讨论),String类,以及一些包含某些基本类型的特殊类:Character,Byte,Short和Integer。 (Java 1.6)

虽然基元与==进行比较,但switch方法肯定在Java 1.6(及更早版本)中使用这种比较。