occurred has excepciones error java exception

has - throw exception java



La excepción es tragada por finalmente (7)

static int retIntExc() throws Exception{ int result = 1; try { result = 2; throw new IOException("Exception rised."); } catch (ArrayIndexOutOfBoundsException e) { System.out.println(e.getMessage()); result = 3; } finally { return result; } }

Un amigo mío es un desarrollador de .NET y actualmente está migrando a Java y me hace la siguiente pregunta sobre esta fuente. En teoría, esto debe throw IOException("Exception rised.") Y todo el método retIntExc() debe retIntExc() throws Exception . Pero nada sucede, el método devuelve 2.

No he probado su ejemplo, pero creo que este no es el comportamiento esperado.

EDITAR: Gracias por todas las respuestas. Algunos de ustedes han ignorado el hecho de que el método se llama retIntExc , lo que significa que este es solo un ejemplo experimental / de prueba, que muestra un problema en la mecánica de lanzar / atrapar. No necesitaba ''arreglar'', necesitaba una explicación de por qué sucede esto.


Al poner return en el método finally, se anula la excepción lanzada y se devuelve el resultado. Tu código debería ser algo como esto:

static int retIntExc() throws Exception{ int result = 1; try { result = 2; throw new IOException("Exception rised."); } catch (ArrayIndexOutOfBoundsException e) { System.out.println(e.getMessage()); result = 3; } finally { // do something } // it gets here only when exception is not thrown return result; }


Devolverá 2 porque

finally siempre ejecuta


El bloque finally se ejecuta sin importar qué excepción se arroje. No solo se ejecuta después de que las excepciones son capturadas por los bloques catch usted declara. Se ejecuta después del bloque try y las excepciones capturadas si las hay . Si su método arroja una excepción, no puede devolver nada a menos que lo trague dentro de su método y arroje el result . Pero no puedes tener ambos.

Además, a menos que su método tenga otro código, ArrayIndexOutOfBoundsException se encontrará ArrayIndexOutOfBoundsException .


Esto se debe a que emite una declaración de devolución antes de que la excepción pase a través y, por lo tanto, se devuelve un valor válido. No se puede devolver un valor y lanzar una excepción.

Quitar el bloque final alrededor de la devolución dará el comportamiento que desee.


La clase IOException no es un elemento secundario de la clase ArrayIndexOutOfBoundsException , por lo que nunca se ejecutará la parte catch.

Si cambias a este, devolverá 3.

static int retIntExc() throws Exception{ int result = 1; try { result = 2; throw new ArrayIndexOutOfBoundsException ("Exception rised."); } catch (ArrayIndexOutOfBoundsException e) { System.out.println(e.getMessage()); result = 3; } finally { return result; } }


No veo por qué esto no sería un comportamiento esperado. Al final de este bloque de código el resultado es igual a 2.

static int retIntExc() throws Exception{ int result = 1; try { result = 2;

Luego lanza una excepción, pero su bloque catch captura excepciones de un tipo diferente para que no se ejecute nada.

throw new IOException("Exception rised."); } catch (ArrayIndexOutOfBoundsException e) { ... }

Se garantiza que el bloque finally se ejecutará, por lo que el paso final es devolver 2.

Este retorno exitoso anula la excepción de burbujeo. Si desea que la excepción continúe burbujeando, no debe regresar en el bloque finally.


Es por eso que no puedes regresar de un bloque final en C # :)

Sin embargo, es absolutamente el comportamiento establecido en la Especificación del lenguaje Java. Se especifica en la sección 14.20.2 .

Si el bloque final se completa bruscamente por la razón S, entonces la instrucción try se completa abruptamente por la razón S (y el lanzamiento del valor V se descarta y se olvida).

Regresar es un ejemplo de completar abruptamente; si el bloque finally lanzó una excepción, también se completará abruptamente, perdiendo la excepción original.

La cita anterior era de este conjunto anidado de viñetas, omitiendo las opciones que no son aplicables aquí:

  • Si la ejecución del bloque try se completa abruptamente debido a un lanzamiento de un valor V, entonces hay una opción:
    • Si el tipo de V en tiempo de ejecución no es asignable al parámetro de ninguna cláusula catch de la instrucción try, entonces se ejecuta el bloque finally. Entonces hay una opción:
      • Si el bloque final se completa bruscamente por la razón S, entonces la instrucción try se completa abruptamente por la razón S (y el lanzamiento del valor V se descarta y se olvida).