Java 7 String switch反编译:意外指令 [英] Java 7 String switch decompiled: unexpected instruction

查看:197
本文介绍了Java 7 String switch反编译:意外指令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经反编译了一个使用新的Java 7字符串切换功能的非常简单的类。

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

该类:

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 7javap,会生成一组有趣的指令(完整的反汇编代码可以在这里找到) ):

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

LOOKUPSWITCH是一条指令当switch case稀疏并且可以替换TABLESWITCH时使用,这是switch语句的默认指令。

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.

所以问题是,为什么我们看到一个LOOKUPSWITCH接着是TABLESWITCH?

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

谢谢
Luciano

Thanks Luciano

推荐答案

在交换机中使用字符串找到正确的case语句是一个两步过程。

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


  1. 计算开关字符串的哈希码,并在其中寻找'哈希码匹配' case语句,这是通过LOOKUPSWITCH完成的。注意LOOKUPSWITCH下的大整数,这些是case语句中字符串的哈希码。

  2. 现在2个字符串可以有相同的哈希码,但不太可能。因此,仍然必须进行实际的字符串比较。因此,一旦匹配哈希码,就将交换字符串与匹配的case语句中的字符串进行比较。 LOOKUPSWITCH和TABLESWITCH之间的指令就是这样做的。确认匹配后,将通过TABLESWITCH达到匹配的case语句要执行的代码。

另请注意,它很有用指定您使用的编译器 - javac或 ECJ (用于java的Eclipse编译器)。两个编译器都可能以不同方式生成字节码。

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.

这篇关于Java 7 String switch反编译:意外指令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆