31

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

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

4

7 回答 7

19

两者都不。它使用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
于 2012-08-18T16:15:37.273 回答
12

正如您从这个答案中看到的那样,Java switch(至少在 1.7 之前)并不总是编译成== or .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;
}

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

于 2012-08-18T16:13:32.550 回答
7

从这里复制

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

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

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

于 2012-08-18T16:15:39.203 回答
1

1.在出现之前Java 7"==",因为我们可以使用integer和char来做switch case,而且因为它们是原始的,所以必须是"=="

2. from Java 7, String 也可以在 switch case中使用,并且 String 是一个object,".equals"被使用。

我想添加这个......这"=="是用来比较Object Reference Variable而不是 Object 本身。使用".equals"我们比较对象

于 2012-08-18T16:10:18.367 回答
0

开关适用于 byte、short、char 和 int 原始数据类型。它还适用于枚举类型(在 Enum Types 中讨论)、String 类和一些包装某些原始类型的特殊类:Character、Byte、Short 和 Integer。(Java 1.6)

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

于 2012-08-18T16:14:00.110 回答
-1

如果使用 pre 1.7 Java 我假设它使用

==

因为对于 int 你不能做 equals 例如,在枚举的情况下,equals 和 == 将返回相同

编辑

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

 tableswitch
于 2012-08-18T16:09:18.197 回答
-1

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

于 2012-08-18T16:12:14.013 回答