Un comentario (del usuario soc ) sobre una respuesta a una pregunta sobre la optimización de la llamada de cola mencionó que Java 7 tiene una nueva característica llamada "excepciones suprimidas", debido a "la adición de ARM" (¿soporte para CPU ARM?).
¿Qué es una "excepción suprimida" en este contexto? En otros contextos, una "excepción suprimida" sería una excepción que se detecta y luego se ignora (rara vez es una buena idea); esto es claramente algo diferente.
Respuestas:
Creo que el comentarista se refiere a una excepción que se ignora parcialmente cuando se lanza dentro del
finally
bloque implícito de un bloque try-with-resources , en el contexto de una excepción existente que se lanza desde eltry
bloque:(Eso es citar una sección llamada "Excepciones suprimidas" de la página vinculada).
fuente
finally
bloque lanza una excepción cuando eltry
bloque también lanzó una excepción, la excepción original de latry
el bloque se pierde o se "suprime" (consulte http://accu.org/index.php/journals/236 para obtener más información). Java 7 acaba de agregar un método conveniente para almacenar la excepción delfinally
bloque porquefinally
se genera implícitamente mediante try-with-resources.Para aclarar la cita en la respuesta de Jon, solo se puede lanzar una excepción por un método (por ejecución) pero es posible, en el caso de a
try-with-resources
, que se generen múltiples excepciones. Por ejemplo, uno podría lanzarse al bloque y otro podría lanzarse desde el implícitofinally
proporcionado portry-with-resources
.El compilador tiene que determinar cuál de estos lanzará "realmente". Elige lanzar la excepción generada en el código explícito (el código en el
try
bloque) en lugar de la que arroja el código implícito (elfinally
bloque). Por lo tanto, las excepciones lanzadas en el bloque implícito se suprimen (ignoran). Esto solo ocurre en el caso de múltiples excepciones.fuente
try
... engorrosasfinally
al abrir eclose()
ingresar archivos: stackoverflow.com/questions/3305405/…Exception(Exception cause)
constructor se usa para envolver una excepción causante en otra que podría ser más descriptiva. Sin embargo, en este caso estamos hablando de dos excepciones distintas para las que no existe una relación causal. La excepción A no causó la excepción B, por lo que no tendría sentido envolver una en la otra. Además, está asumiendo que el codificador está lanzando explícitamente la segunda excepción y tiene acceso a la primera. Ese no sería el caso si ambos fueran lanzados por llamadas de biblioteca.If an exception is thrown from the try block and one or more exceptions are thrown from the try-with-resources statement, then those exceptions thrown from the try-with-resources statement are suppressed
Antes de Java7; Hay excepciones en el código, pero se ignoraron de alguna manera.
p.ej)
public class SuppressedExceptions { public static void main(String[] args) throws Exception { try { callTryFinallyBlock(); } catch (Exception e) { e.printStackTrace(); **//Only Finally Exception is Caught** } } private static void callTryFinallyBlock() throws Exception { try { throw new TryException(); **//This is lost** } finally { FinallyException fEx = new FinallyException(); throw fEx; } } } class TryException extends Exception { } class FinallyException extends Exception { }
Se agregaron un nuevo constructor y dos nuevos métodos a la clase Throwable en JDK 7. Estos son los siguientes:
Throwable.getSupressed(); // Returns Throwable[] Throwable.addSupressed(aThrowable);
con este nuevo enfoque, también podemos manejar las excepciones suprimidas.
public class SuppressedExceptions { public static void main(String[] args) throws Exception { try { callTryFinallyBlock(); } catch (Exception e) { e.printStackTrace(); for(Throwable t: e.getSuppressed()) { t.printStackTrace(); } } } private static void callTryFinallyBlock() throws Exception { Throwable t = null; try { throw new TryException(); } catch (Exception e) { t = e; } finally { FinallyException fEx = new FinallyException(); if(t != null)fEx.addSuppressed(t); throw fEx; } } } class TryException extends Exception { } class FinallyException extends Exception { }
También consciente de que esto es diferente de las excepciones encadenadas (se introdujeron con JDK 1.4 y estaban destinadas a hacer posible rastrear fácilmente las relaciones causales entre excepciones).
fuente
Concediendo el siguiente código:
public class MultipleExceptionsExample { static class IOManip implements Closeable{ @Override public void close() { throw new RuntimeException("from IOManip.close"); } } public static void main(String[] args) { try(IOManip ioManip = new IOManip()){ throw new RuntimeException("from try!"); }catch(Exception e){ throw new RuntimeException("from catch!"); }finally{ throw new RuntimeException("from finally!"); } } }
Con todas las líneas obtendrás:
java.lang.RuntimeException: from finally!
Eliminando el
finally
bloque obtendrás:java.lang.RuntimeException: from catch!
Eliminando el
catch
bloque obtendrás:Exception in thread "main" java.lang.RuntimeException: from try! Suppressed: java.lang.RuntimeException: from IOManip.close
fuente
Las excepciones suprimidas son excepciones adicionales que ocurren dentro de una declaración try-with-resources ( introducida en Java 7 ) cuando los
AutoCloseable
recursos están cerrados. Debido a que pueden ocurrir múltiples excepciones al cerrarAutoCloseable
recursos, las excepciones adicionales se adjuntan a una excepción principal como excepciones suprimidas .Al observar el código de bytes de un fragmento de código de muestra try-with-resources, se utilizan manejadores de excepciones JVM estándar para acomodar la semántica try-with-resources.
fuente
También puede suprimir Excepciones en Java 6 (un pequeño truco involucrado),
Creé una utilidad que maneja de forma transparente la supresión de excepciones en Java 1.6 y Java 1.7. Puedes encontrar la implementación aquí
Todo lo que necesitas es llamar:
public static <T extends Throwable> T suppress(final T t, final Throwable suppressed)
para suprimir una excepción, y
public static Throwable [] getSuppressed(final Throwable t) {
para obtener las excepciones suprimidas de una excepción, en caso de que alguien todavía use Java 1.6
fuente
ARM - Gestión automática de recursos (introducido desde Java 7)
Tome un ejemplo muy simple
static String readFirstLineFromFileWithFinallyBlock(String path) throws IOException { BufferedReader br = new BufferedReader(new FileReader(path)); try { return br.readLine(); } finally { if (br != null) br.close(); } }
Ahora, si la
readLine()
función arroja Exception y luego incluso laclose()
función [en el bloque finalmente] arroja una excepción, entonces se le da más prioridad a la última y se la devuelve a la función que llama. En este caso elException thrown by the readLine() method is ignored/suppressed
. Puede encadenar la excepción causante en su excepción y volver a lanzar su excepción desde el bloqueo final.Dado
java 7
que se ha proporcionado funcionalidad para recuperar excepciones suprimidas. Puede llamar a lapublic final java.lang.Throwable[] getSuppressed()
función en el objeto arrojadizo capturado para ver las Excepciones suprimidas.Por ejemplo.
static String readFirstLineFromFileWithFinallyBlock(String path) throws Exception { try (BufferedReader br = new BufferedReader(new FileReader(path));) { return br.readLine(); } }
Ahora, si
br.readLine();
se lanza una líneaException1
y luego digamos queException2
se lanza mientras se cierra el recurso [Imagine que esto sucede en un bloque final implícito que crea la instrucción try-with-resource], entonces Exception1 suprime Exception2.Algunos puntos a tener en cuenta aquí:
He compilado la mayoría de los escenarios posibles con fragmentos de código y salida en la siguiente publicación.
Excepciones suprimidas en java 7
Espero que ayude.
fuente
Exception
que se origina en el bloque try {} no se suprimirá automáticamente. El programador puede optar por hacerlo, pero usted no lo ha hecho. Solo try-with-resources, cuando sea necesario, suprimirá las excepciones automáticamente. Y cuando lo haga, será la excepción de su bloqueo final equivalente lo que se suprimirá.Creo que esto tiene que ver con la "facilidad de excepción encadenada". Afectará cómo esta función maneja una excepción a medida que evoluciona el seguimiento de la pila. Con el tiempo, las excepciones que forman parte de un grupo de excepciones encadenadas se pueden suprimir. Consulte la documentación Throwable para obtener más detalles.
fuente