Java 7 String switch 反编译:意外指令

发布于 2024-11-28 03:03:21 字数 1761 浏览 2 评论 0原文

我反编译了一个非常简单的类,它使用新的 Java 7 String Switch 功能。

类:

public class StringSwitch {

    public static void main(String[] args) {

        final String color = "red";
        switch (color) {
            case "red":
                System.out.println("IS RED!");
                break;
            case "black":
                System.out.println("IS BLACK");
                break;
            case "blue":
                System.out.println("IS BLUE");
                break;
            case "green":
                System.out.println("IS GREEN");
                break;
        }

    }

}

针对此类运行 Java 7“javap”,生成一组有趣的指令(完整的反汇编代码可在 这里):

public static void main(java.lang.String[]);
    flags: ACC_PUBLIC, ACC_STATIC

    Code:
      stack=2, locals=4, args_size=1
        ...
        12: lookupswitch  { // 4

                  112785: 56

                 3027034: 84

                93818879: 70

                98619139: 98
                 default: 109
            }
        56: aload_2       
        57: ldc           #2                  // String red
        ...       
       110: tableswitch   { // 0 to 3

                       0: 140

                       1: 151

                       2: 162

                       3: 173
                 default: 181
            }
       140: getstatic     #8                  // Field java/lang/System.out:Ljava/io/PrintStream;
       143: ldc           #9                  // String IS RED!
       ...
       181: return

“LOOKUPSWITCH”是switch case稀疏时使用的指令,可以替代TABLESWITCH,即“switch”语句的默认指令。

那么,问题是,为什么我们会看到“LOOKUPSWITCH”后面跟着“TABLESWITCH”?

谢谢 卢西亚诺

I have decompiled a very simple class that uses the new Java 7 String Switch feature.

The class:

public class StringSwitch {

    public static void main(String[] args) {

        final String color = "red";
        switch (color) {
            case "red":
                System.out.println("IS RED!");
                break;
            case "black":
                System.out.println("IS BLACK");
                break;
            case "blue":
                System.out.println("IS BLUE");
                break;
            case "green":
                System.out.println("IS GREEN");
                break;
        }

    }

}

Running the Java 7 "javap" against this class, generates an interesting set of instructions (the complete disassembled code is available here):

public static void main(java.lang.String[]);
    flags: ACC_PUBLIC, ACC_STATIC

    Code:
      stack=2, locals=4, args_size=1
        ...
        12: lookupswitch  { // 4

                  112785: 56

                 3027034: 84

                93818879: 70

                98619139: 98
                 default: 109
            }
        56: aload_2       
        57: ldc           #2                  // String red
        ...       
       110: tableswitch   { // 0 to 3

                       0: 140

                       1: 151

                       2: 162

                       3: 173
                 default: 181
            }
       140: getstatic     #8                  // Field java/lang/System.out:Ljava/io/PrintStream;
       143: ldc           #9                  // String IS RED!
       ...
       181: return

The "LOOKUPSWITCH" is an instruction used when the switch case is sparse and can replace the TABLESWITCH, that is the default instruction for "switch" statements.

So, the question is, why are we seeing a "LOOKUPSWITCH" followed by a "TABLESWITCH"?

Thanks
Luciano

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

意中人 2024-12-05 03:03:21

使用 switch 中的字符串查找正确的 case 语句需要两步过程。

  1. 计算 switch 字符串的哈希码并在 case 语句中查找“哈希码匹配”,这是通过 LOOKUPSWITCH 完成的。注意 LOOKUPSWITCH 下的大整数,这些是 case 语句中字符串的哈希码。
  2. 现在,两个字符串可以具有相同的哈希码,尽管可能性不大。因此,实际的字符串比较仍然必须进行。因此,一旦哈希码匹配,就会将 switch 字符串与匹配的 case 语句中的字符串进行比较。 LOOKUPSWITCH 和 TABLESWITCH 之间的指令正是执行此操作。一旦确认匹配,就会通过 TABLESWITCH 到达匹配的 case 语句要执行的代码。

另请注意,指定您使用的编译器很有用 - javac 或 ECJ(Java 的 Eclipse 编译器)。两种编译器生成的字节码可能不同。

With strings in switch finding the correct case statement is a 2 step process.

  1. Compute the hashcode of the switch string and look for a 'hashcode match' among the case statements, this is done via LOOKUPSWITCH. Note the large integer numbers under LOOKUPSWITCH, these are hashcodes of the strings in case statements.
  2. Now 2 strings can have the same hashcode, however unlikely it may be. Hence the actual string comparison must still take place. Hence once the hashcode is matched, the switch string is compared with the string in the matched case statement. The instructions between LOOKUPSWITCH and TABLESWITCH do exactly this. Once the match is confirmed, the code to be executed for the matched case statement is reached via TABLESWITCH.

Also note that it is useful to specify which compiler you used - javac or ECJ (Eclipse compiler for java). Both compilers may generate the bytecode differently.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文