Переключатель Java 7 String декомпилирован: неожиданная инструкция - PullRequest
14 голосов
/ 05 августа 2011

Я декомпилировал очень простой класс, который использует новую функцию переключения строк Java 7.

Класс:

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" - это инструкция, используемая, когда регистр переключателя редкий, и может заменить TABLESWITCH, которая является инструкцией по умолчанию для операторов "switch".

Итак, вопрос в том, почему мы видим «LOOKUPSWITCH», за которым следует «TABLESWITCH»?

Спасибо Luciano

1 Ответ

17 голосов
/ 05 августа 2011

Со строками в переключателе поиск правильного оператора case является двухэтапным процессом.

  1. Вычислить хеш-код строки переключателя и найти «совпадение хеш-кода» среди операторов case, это делается с помощью LOOKUPSWITCH. Обратите внимание на большие целые числа в LOOKUPSWITCH, это хеш-коды строк в операторах case.
  2. Теперь 2 строки могут иметь один и тот же хэш-код, однако вряд ли это так. Следовательно, фактическое сравнение строк все еще должно иметь место. Следовательно, после совпадения хеш-кода строка переключателя сравнивается со строкой в ​​операторе соответствия. Инструкции между LOOKUPSWITCH и TABLESWITCH делают именно это. Как только совпадение подтверждено, код, который должен быть выполнен для оператора сопоставления регистра, достигается через TABLESWITCH.

Также обратите внимание, что полезно указать, какой компилятор вы использовали - javac или ECJ (компилятор Eclipse для java). Оба компилятора могут генерировать байт-код по-разному.

...