what method manage lanzar exceptions java exception language-lawyer throw checked-exceptions

manage - throw exception method java



¿Por qué está permitido lanzar un tipo de excepción marcada en este caso? (3)

Creo que la redacción en §14.18 La Declaración de throw , a la que te refieres, es un error en el JLS: texto que debería haberse actualizado con Java SE 7, y no lo fue.

El bit del texto JLS que describe el comportamiento deseado se encuentra en §11.2.2 Análisis de excepciones de las declaraciones :

Una declaración de throw cuya expresión arrojada es un parámetro de excepción final o efectivamente final de una cláusula catch C puede lanzar una clase de excepción E iff:

  • E es una clase de excepción que el bloque try de la instrucción try que declara que C puede lanzar; y
  • E es la asignación compatible con cualquiera de las clases de excepción detectables de C; y
  • E no es compatible con la asignación con ninguna de las clases de excepción detectables de las cláusulas catch declaradas a la izquierda de C en la misma declaración de try .

El primer punto es el relevante; debido a que el parámetro catch -clause t es efectivamente final (lo que significa que nunca se asigna ni se incrementa ni disminuye; consulte §4.12.4 Variables final ), el throw t solo puede lanzar algo que el bloque try podría lanzar.

Pero como usted dice, la verificación en tiempo de compilación en §14.18 no hace ninguna concesión para esto. §11.2.2 no decide qué está permitido y qué no; más bien, se supone que es un análisis de las consecuencias de las diversas restricciones sobre lo que se puede lanzar. (Este análisis se retroalimenta en partes más normativas de la especificación - §14.18 en sí lo usa en su segundo punto de viñeta - pero §14.18 no puede simplemente decir "es un error de compilación si lanza una excepción que no puede". lanzar por §11.2.2 ", porque eso sería circular.)

Así que creo que §14.18 debe ajustarse para adaptarse a la intención de §11.2.2.

¡Buen descubrimiento!

Noté por accidente que esta declaración de throw (extraída de un código más complejo) se compila:

void foo() { try { } catch (Throwable t) { throw t; } }

Por un breve pero feliz momento, pensé que las excepciones controladas finalmente habían decidido simplemente morir, pero aún así se pone honesto con esto:

void foo() { try { } catch (Throwable t) { Throwable t1 = t; throw t1; } }

El bloque try no tiene que estar vacío; Parece que puede tener código siempre y cuando ese código no arroje una excepción marcada. Parece razonable, pero mi pregunta es: ¿qué regla en la especificación del lenguaje describe este comportamiento? Por lo que puedo ver, §14.18 La Declaración de lanzamiento lo prohíbe explícitamente, porque el tipo de la expresión t es una excepción comprobada, y no se ha capturado o declarado como arrojado. (?)


Este comportamiento se describe en detalle en el JLS en 11.2. Verificación de excepciones en tiempo de compilación :

Una declaración de throw cuya expresión arrojada es un parámetro de excepción final o efectivamente final de una cláusula catch C puede lanzar una clase de excepción E iff:

  • E es una clase de excepción que el bloque try de la instrucción try que declara que C puede lanzar ; y

  • E es la asignación compatible con cualquiera de las clases de excepción detectables de C; y

  • E no es compatible con la asignación con ninguna de las clases de excepción detectables de las cláusulas catch declaradas a la izquierda de C en la misma declaración de try .

(Énfasis mío.)

El segundo ejemplo falla porque t1 no es un "parámetro de excepción de una cláusula catch ".


Esto se debe a un cambio que se incluyó en Project Coin , introducido en Java 7, para permitir el manejo de excepciones generales con el reenvío de la excepción original. Aquí hay un ejemplo que funciona en Java 7 pero no en Java 6:

public static demoRethrow() throws IOException { try { throw new IOException("Error"); } catch(Exception exception) { /* * Do some handling and then rethrow. */ throw exception; } }

Puedes leer el artículo completo explicando los cambios here .