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(及更早版本)中使用这种比较。