try statement funciona excepciones ejemplos conclusion como catch java exception

statement - try catch finally java ejemplos



Excepción lanzada dentro del bloque catch: ¿se atrapará nuevamente? (9)

Esto puede parecer una pregunta de programación 101 y pensé que sabía la respuesta, pero ahora me veo en la necesidad de volver a verificarlo. En este fragmento de código a continuación, ¿la excepción lanzada en el primer bloque de captura será capturada por el bloque de captura de excepción general a continuación?

try { // Do something } catch(IOException e) { throw new ApplicationException("Problem connecting to server"); } catch(Exception e) { // Will the ApplicationException be caught here? }

Siempre pensé que la respuesta sería no, pero ahora tengo un comportamiento extraño que podría ser causado por esto. La respuesta es probablemente la misma para la mayoría de los idiomas, pero estoy trabajando en Java.


Como dije antes ...
Añadiría que si tiene problemas para ver lo que está sucediendo, si no puede reproducir el problema en el depurador, puede agregar una traza antes de volver a lanzar la nueva excepción (con el viejo System.out.println empeorado) , con un buen sistema de registro como log4j de lo contrario).


La Especificación del lenguaje Java dice en la sección 14.19.1:

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 de tiempo de ejecución se puede asignar al parámetro de cualquier cláusula de captura de la instrucción try, entonces se selecciona la primera cláusula catch (la más a la izquierda). El valor V se asigna al parámetro de la cláusula de captura seleccionada, y se ejecuta el Bloque de esa cláusula de captura. Si ese bloque se completa normalmente, la instrucción try se completa normalmente; si ese bloque se completa abruptamente por algún motivo, la instrucción try se completa abruptamente por el mismo motivo.

Referencia: http://java.sun.com/docs/books/jls/second_edition/html/statements.doc.html#24134

En otras palabras, la primera captura adjunta que puede manejar la excepción sí lo hace, y si se descarta una excepción de esa captura, eso no está dentro del alcance de ninguna otra captura para la prueba original, por lo que no intentarán manejarla.

Una cosa relacionada y confusa de saber es que en una estructura try [catch] final, un bloque finally puede arrojar una excepción y, de ser así, se pierde cualquier excepción lanzada por el bloque try o catch. Eso puede ser confuso la primera vez que lo ves.


La publicación anterior pero la variable "e" debe ser única:

try { // Do something } catch(IOException ioE) { throw new ApplicationException("Problem connecting to server"); } catch(Exception e) { // Will the ApplicationException be caught here? }


No será capturado por el segundo bloque catch. Cada excepción se detecta solo cuando está dentro de un bloque de prueba. Sin embargo, puedes anidar intentos (aunque no es una buena idea en general):

try { doSomething(); } catch (IOException) { try { doSomething(); } catch (IOException e) { throw new ApplicationException("Failed twice at doSomething" + e.toString()); } } catch (Exception e) { }


No, como dijo Chris Jester-Young, se lanzará al próximo try-catch en la jerarquía.


No, ya que el nuevo throw no está directamente en el bloque try .


No, ya que las capturas se refieren al mismo bloque de prueba, por lo que lanzar desde dentro de un bloque de catch sería atrapado por un bloque try adjunto (probablemente en el método que llamó a este)


No. Es muy fácil de verificar.

public class Catch { public static void main(String[] args) { try { throw new java.io.IOException(); } catch (java.io.IOException exc) { System.err.println("In catch IOException: "+exc.getClass()); throw new RuntimeException(); } catch (Exception exc) { System.err.println("In catch Exception: "+exc.getClass()); } finally { System.err.println("In finally"); } } }

Debe imprimir:

In catch IOException: class java.io.IOException In finally Exception in thread "main" java.lang.RuntimeException at Catch.main(Catch.java:8)

Técnicamente, eso podría haber sido un error del compilador, un comportamiento dependiente de la implementación, no especificado, o algo así. Sin embargo, el JLS está bastante bien definido y los compiladores son lo suficientemente buenos para este tipo de cosas simples (caso de esquina de genéricos puede ser un asunto diferente).

También tenga en cuenta que si intercambia los dos bloques catch, no se compilará. La segunda captura sería completamente inalcanzable.

Tenga en cuenta que el bloque finally siempre se ejecuta incluso si se ejecuta un bloque catch (excepto casos tontos, como bucles infinitos, adjuntar a través de la interfaz de herramientas y matar el hilo, reescribir bytecode, etc.).


Si desea lanzar una excepción desde el bloque catch, debe informar su método / clase / etc. que necesita arrojar dicha excepción. Al igual que:

public void doStuff() throws MyException { try { //Stuff } catch(StuffException e) { throw new MyException(); } }

Y ahora tu compilador no te gritará :)