2011-08-05 11 views
12

Dekompilowałem bardzo prostą klasę, która wykorzystuje nową funkcję przełączania Javy 7 String.Java 7 Dekodowany przełącznik łańcuchowy: nieoczekiwana instrukcja

Klasa:

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; 
     } 

    } 

} 

Uruchomienie "javap" Java 7 przeciwko tej klasy generuje ciekawy zestaw instrukcji (kompletny kod zdemontowany jest dostępny 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 "to instrukcja używana, gdy przypadek przełącznika jest rozrzedzony i może zastąpić TABLESWITCH, czyli domyślną instrukcję dla instrukcji" switch ".

Pytanie brzmi, dlaczego widzimy "LOOKUPSWITCH", a następnie "TABLESWITCH"?

Dzięki Luciano

Odpowiedz

15

Z ciągów w przełączniku znalezienie odpowiedniej oświadczenie przypadku jest to proces, krok 2.

  1. Oblicz kod skrótu łańcucha przełącznika i znajdź "dopasowanie hashcode" wśród instrukcji case, odbywa się to za pomocą LOOKUPSWITCH. Zauważ duże liczby całkowite pod LOOKUPSWITCH, są to hashcody ciągów w instrukcjach case.
  2. Teraz 2 ciągi mogą mieć ten sam kod skrótu, jednak jest to mało prawdopodobne. W związku z tym rzeczywiste porównanie ciąg musi nadal mieć miejsce. W związku z tym, po dopasowaniu hashcode, łańcuch przełączników jest porównywany z łańcuchem w dopasowanej instrukcji case. Instrukcje pomiędzy LOOKUPSWITCH i TABLESWITCH robią dokładnie to. Po potwierdzeniu, kod, który zostanie wykonany dla dopasowanej instrukcji case, zostanie osiągnięty przez TABLESWITCH.

Należy również pamiętać, że przydatne jest określenie używanego kompilatora - javac lub ECJ (Kompilator Eclipse dla języka Java). Oba kompilatory mogą różnie generować kod bajtowy.

+0

Dzięki za odpowiedź. Ma sens. –

Powiązane problemy