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

Rag*_*ood 27 java switch-statement

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

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

Joã*_*lva 18

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

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
Run Code Online (Sandbox Code Playgroud)

  • 这不是真的.当您的案例中存在间隙时(多个间隙或单个间隙的值差异大于1),它会使用查找切换.否则,它使用更有效的tableswitch.您可以在https://www.artima.com/underthehood/flowP.html找到更多信息 (2认同)

Ale*_*ing 11

这个答案可以看出,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;
}
Run Code Online (Sandbox Code Playgroud)

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


Ami*_*nde 5

这里复制

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

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

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