Java的开关如何在引擎盖下工作?

2022-09-01 09:52:34

Java的switch语句是如何在引擎盖下工作的?它如何将正在使用的变量的值与案例部分中给出的值进行比较?它是否使用 或 ,或者它完全是其他东西?==.equals()

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


答案 1

也不。它使用查找开关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

答案 2

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

请注意,这仅用于针对密集键进行检查的语句。例如,检查枚举值的所有可能性可能会产生此主要实现(内部称为 )。switchtableswitch

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

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;
}

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