propagacion - tipos de excepciones en java netbeans
¿Por qué la captura de Exception no captura RuntimeException? (5)
La Exception
captura detectará una Exception
RuntimeException
Esto es muy extraño para mí. RuntimeException
hereda de Exception
, que hereda de Throwable
.
catch(Exception exc) { /* won''t catch RuntimeException */
pero
catch(Throwable exc) { /* will catch RuntimeException */
Sé que RuntimeException
es especial ya que no está marcado. Pero a mi entender, eso se aplica solo a si las excepciones tienen que ser declaradas, no si son capturadas. E incluso entonces, no sé por qué esta lógica se rompería al atrapar a Throwable.
Esto es bastante relevante para mí ya que tengo una situación en la que se pueden lanzar RuntimeExceptions en una operación de terminal. No estoy seguro del nombre de este patrón, pero algo así como mi clase EmailRoller
toma una serie de Callbacks
de Callbacks
. El código se ve así:
for(Callback cb : callbacks) {
try {
cb.call(item);
}
catch(Exception exc) {
logger.error("Error in callback: ", exc);
}
}
Así que este es un caso en el que algo como un OOME necesita volar, porque si una de estas devoluciones de llamada consume toda la memoria de la máquina, eso seguro que afectará la ejecución de las otras. Pero una NullPointerException
? ¿O una IndexOutOfBoundsException
? Eso afectará la devolución de llamada pero no evitará que los otros se ejecuten.
Además, esto es un poco de un diseño empresarial. Diferentes programadores o equipos pueden agregar devoluciones de llamada para procesar el elemento, pero deben estar aislados unos de otros. Esto significa que, como el programador responsable de aislar estas devoluciones de llamadas, no debería confiar en ellas para asegurarse de que los errores no se escapen. La Exception
captura debe ser sobre la línea correcta, pero no porque RuntimeException
se RuntimeException
través. Entonces mi pregunta más general es: ¿cuál es un buen patrón aquí? Solo catch(Exception | RuntimeException exc)
, que creo que es un error de sintaxis debido a la herencia?
La premisa de la pregunta es defectuosa, ya que la captura de la Exception
captura la Exception
RuntimeException
. Código demo:
public class Test {
public static void main(String[] args) {
try {
throw new RuntimeException("Bang");
} catch (Exception e) {
System.out.println("I caught: " + e);
}
}
}
Salida:
I caught: java.lang.RuntimeException: Bang
Tu bucle tendrá problemas si:
-
callbacks
es nula - cualquier cosa modifica las
callbacks
mientras el bucle se está ejecutando (si fuera una colección en lugar de una matriz)
Tal vez eso es lo que estás viendo?
Me enfrenté a un escenario similar. Ocurrió porque la iniciación de classA dependía de la inicialización de classB. Cuando el bloque estático de classB se enfrentó a la excepción de tiempo de ejecución, classB no se inicializó. Debido a esto, classB no lanzó ninguna excepción y la inicialización de classA también falló.
class A{//this class will never be initialized because class B won''t intialize
static{
try{
classB.someStaticMethod();
}catch(Exception e){
sysout("This comment will never be printed");
}
}
}
class B{//this class will never be initialized
static{
int i = 1/0;//throw run time exception
}
public static void someStaticMethod(){}
}
Y sí ... capturar Exception
también detectará excepciones de tiempo de ejecución.
catch (Exception ex) { ... }
Se captura RuntimeException.
Lo que pongas en el bloque catch se capturará, así como las subclases de él.
class Test extends Thread
{
public void run(){
try{
Thread.sleep(10000);
}catch(InterruptedException e){
System.out.println("test1");
throw new RuntimeException("Thread interrupted..."+e);
}
}
public static void main(String args[]){
Test t1=new Test1();
t1.start();
try{
t1.interrupt();
}catch(Exception e){
System.out.println("test2");
System.out.println("Exception handled "+e);
}
}
}
Su salida no contiene test2, por lo que no controla la excepción de tiempo de ejecución. @jon skeet, @Jan Zyka