sirve settitle setlookandfeel que para look how feel example change and java jvm bytecode

settitle - Extraña entrada de tabla de excepción producida por Sun''s javac



setlookandfeel java example (3)

Dado este programa:

class Test { public static void main(String[] args) { try { throw new NullPointerException(); } catch (NullPointerException npe) { System.out.println("In catch"); } finally { System.out.println("In finally"); } } }

Sun''s javac (v 1.6.0_24) produce el siguiente bytecode:

public static void main(java.lang.String[]); // Instantiate / throw NPE 0: new #2; // class NullPointerException 3: dup 4: invokespecial #3; // Method NullPointerException."<init>":()V 7: athrow // Start of catch clause 8: astore_1 9: getstatic #4; // Field System.out 12: ldc #5; // "In catch" 14: invokevirtual #6; // Method PrintStream.println 17: getstatic #4; // Field System.out // Inlined finally block 20: ldc #7; // String In finally 22: invokevirtual #6; // Method PrintStream.println 25: goto 39 // Finally block // store "incomming" exception(?) 28: astore_2 29: getstatic #4; // Field System.out 32: ldc #7; // "In finally" 34: invokevirtual #6; // Method PrintStream.println // rethrow "incomming" exception 37: aload_2 38: athrow 39: return

Con la siguiente tabla de excepción:

Exception table: from to target type 0 8 8 Class NullPointerException 0 17 28 any 28 29 28 any


Mi pregunta es: ¿por qué incluye esa última entrada en la tabla de excepciones?

Según lo entiendo, básicamente dice " si el astore_2 arroja una excepción, astore_2 y vuelve a intentar la misma instrucción ".

Tal entrada se produce incluso con cláusulas vacías try / catch / finally como

try {} catch (NullPointerException npe) {} finally {}

Algunas observaciones

  • El compilador de Eclipse no produce ninguna entrada de tabla de excepción
  • La especificación JVM no documenta ninguna excepción de tiempo de ejecución para la instrucción astore .
  • Sé que es legal para la JVM lanzar VirtualMachineError para cualquier instrucción. Supongo que la entrada peculiar evita que dichos errores se propaguen desde esa instrucción.

Mirando el código fuente de OpenJDK 7, me atrevería a adivinar el motivo de la última entrada de la tabla 28 29 28 any es porque el código que maneja el bytecode de la astore (vea el code comienza en la línea 1871) puede arrojar un java.lang.LinkageError excepción si el valor extraído de la pila de operandos no es un tipo de reference o de dirección de returnAddress (consulte la Especificación de máquina virtual de Java para astore ) y quiere que esta condición de error aparezca en el seguimiento de la pila.

En el caso de que haya un tipo de operando incorrecto en la pila de operandos, la JVM borrará la pila de operandos (deshaciéndose de ese operando defectuoso), pondrá un LinkageError en la pila de operandos y ejecutará de nuevo el bytecode de astore , esta vez ejecutándose con éxito el bytecode astore utilizando una referencia de objeto LinkageError proporcionada por JVM. Consulte la documentación de athrow para más información.

Sospecho que la causa raíz de lanzar un LinkageError durante el procesamiento de astore se debe a las complejidades que introducen las subrutinas JSR / RET en la verificación de 6878713 6932496 (los cambios OpenJDK 6878713 , 6932496 y 7020373 son evidencia reciente de la continua complejidad de JSR ; estoy seguro Sun / Oracle tiene otras pruebas de código cerrado que no estamos viendo en OpenJDK). El cambio OpenJDK 7020373 usa LinkageError para validar / invalidar resultados de prueba.


Según entiendo, la segunda entrada de la tabla de excepción es la cláusula catch all implícita agregada por el compilador para cubrir cualquier excepción / error arrojado en el cuerpo o los manejadores de catch y la tercera entrada es el guardián en esa captura implícita para forzar el flujo a través del finalmente ejecución.


Solo hay dos explicaciones posibles: el compilador contiene un error o está colocando un tipo de marca de agua por razones desconocidas.

Esa entrada es ciertamente falsa porque cualquier excepción lanzada por un bloque finally debe enviar el flujo de ejecución al manejador de excepción externo o finalmente al bloque, pero nunca "ejecutar nuevamente" el mismo bloque finally.

Además, una buena evidencia de que es un error / marca de agua, es el hecho de que Eclipse (y tal vez otros compiladores de Java) no están generando dicha entrada, y aún así las clases generadas por Eclipse funcionan bien en la JVM de Sun.

Dicho esto, esta publicación es interesante porque parece que el archivo de clase es válido y verificado. Si fuera un implementador de JVM, ¡ignoraría esa entrada y llenaría un error para Sun / Oracle!