2011-08-05 13 views
12

新しいJava 7 String Switch機能を使用する非常に単純なクラスを逆コンパイルしました。このクラスに対するJavaの7 "てjavapを実行"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; 
     } 

    } 

} 

、命令の興味深いセット(完全な逆アセンブルコードが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 "ステートメントのデフォルト命令であるTABLESWITCHを置き換えることができるときに使用される命令である。

なぜ、私たちは "ルックアップワッチ"に続いて "テーブルワッチ"を見るのですか?

スイッチ内の文字列が正しい場合ステートメントを見つけると感謝 ルチアーノ

答えて

15

は、2段階のプロセスです。

  1. スイッチ文字列のハッシュコードを計算し、case文の中で「ハッシュコードマッチ」を探します。これはLOOKUPSWITCHを介して行われます。 LOOKUPSWITCHの下にある大きな整数に注意してください。これらはcase文の文字列のハッシュコードです。
  2. 2つの文字列は同じハッシュコードを持つことができますが、そうである可能性は低いです。したがって、実際の文字列の比較はまだ行われなければなりません。したがって、ハッシュコードが一致すると、スイッチ文字列は、一致したcaseステートメントの文字列と比較されます。 LOOKUPSWITCHとTABLESWITCHの間の命令はまさにこれを行います。一致が確認されると、一致したcase文に対して実行されるコードにTABLESWITCHで到達します。

javacまたはECJ(Javaの場合はEclipseコンパイラ)を使用するコンパイラを指定すると便利です。どちらのコンパイラも、バイトコードを別々に生成することがあります。

+0

あなたの答えに感謝します。それは理にかなっています。 –