2011-08-05 11 views
12

He descompilado una clase muy simple que usa la nueva característica Java 7 String Switch.Java 7 Switch de cadena descompilado: instrucción inesperada

La clase:

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

    } 

} 

Ejecución de la "javap" Java 7 en contra de esta clase, genera un interesante conjunto de instrucciones (el código desensamblado completo está disponible 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 

El " LOOKUPSWITCH "es una instrucción que se usa cuando la caja del interruptor es escasa y puede reemplazar a TABLESWITCH, que es la instrucción predeterminada para las instrucciones de" cambio ".

Entonces, la pregunta es, ¿por qué estamos viendo un "LOOKUPSWITCH" seguido de un "TABLESWITCH"?

Gracias Luciano

Respuesta

15

con cadenas en la búsqueda de interruptor de la declaración correcta de los casos es un proceso de 2 pasos.

  1. Calcule el código hash de la cadena de interruptor y busque una 'coincidencia de código hash' entre las declaraciones de caso, esto se hace a través de LOOKUPSWITCH. Tenga en cuenta los números enteros grandes en LOOKUPSWITCH, estos son códigos de hash de las cadenas en las sentencias case.
  2. Ahora 2 cadenas pueden tener el mismo código hash, por improbable que sea. Por lo tanto, la comparación real de cadenas todavía debe tener lugar. Por lo tanto, una vez que coincida el código hash, la cadena del interruptor se compara con la cadena en la declaración de mayúsculas y minúsculas. Las instrucciones entre LOOKUPSWITCH y TABLESWITCH hacen exactamente esto. Una vez que se confirma la coincidencia, el código que se ejecutará para la declaración del caso coincidente se alcanza a través de TABLESWITCH.

También tenga en cuenta que es útil especificar qué compilador utilizó: javac o ECJ (compilador de Eclipse para java). Ambos compiladores pueden generar el bytecode de manera diferente.

+0

Gracias por su respuesta. Tiene sentido. –

Cuestiones relacionadas