¿Puedo detectar varias excepciones de Java en la misma cláusula de captura?
En Java, quiero hacer algo como esto:
try {
...
} catch (/* code to catch IllegalArgumentException, SecurityException,
IllegalAccessException, and NoSuchFieldException at the same time */) {
someCode();
}
...en lugar de:
try {
...
} catch (IllegalArgumentException e) {
someCode();
} catch (SecurityException e) {
someCode();
} catch (IllegalAccessException e) {
someCode();
} catch (NoSuchFieldException e) {
someCode();
}
¿Hay alguna manera de hacer esto?
Esto ha sido posible desde Java 7 . La sintaxis de un bloque multicaptura es:
try {
...
} catch (IllegalArgumentException | SecurityException | IllegalAccessException |
NoSuchFieldException e) {
someCode();
}
Sin embargo, recuerde que si todas las excepciones pertenecen a la misma jerarquía de clases, simplemente puede detectar ese tipo de excepción base.
También tenga en cuenta que no puede capturar ambos ExceptionA
y ExceptionB
en el mismo bloque si ExceptionB
se hereda, directa o indirectamente, de ExceptionA
. El compilador se quejará:
Alternatives in a multi-catch statement cannot be related by subclassing
Alternative ExceptionB is a subclass of alternative ExceptionA
La solución para esto es incluir solo la excepción ancestral en la lista de excepciones, ya que también detectará excepciones del tipo descendiente.
No exactamente antes de Java 7, pero haría algo como esto:
Java 6 y antes
try {
//.....
} catch (Exception exc) {
if (exc instanceof IllegalArgumentException || exc instanceof SecurityException ||
exc instanceof IllegalAccessException || exc instanceof NoSuchFieldException ) {
someCode();
} else if (exc instanceof RuntimeException) {
throw (RuntimeException) exc;
} else {
throw new RuntimeException(exc);
}
}
Java 7
try {
//.....
} catch ( IllegalArgumentException | SecurityException |
IllegalAccessException| NoSuchFieldException exc) {
someCode();
}
No, uno por cliente antes de Java 7.
Puede capturar una superclase, como java.lang.Exception, siempre que realice la misma acción en todos los casos.
try {
// some code
} catch(Exception e) { //All exceptions are caught here as all are inheriting java.lang.Exception
e.printStackTrace();
}
Pero puede que esa no sea la mejor práctica. Sólo debe detectar una excepción cuando tenga una estrategia para manejarla realmente, y registrarla y volver a generarla no es "manejarla". Si no tiene una acción correctiva, es mejor agregarla a la firma del método y dejar que alguien pueda manejar la situación.
Con JDK 7 y posteriores puedes hacer esto:
try {
...
} catch (IllegalArgumentException | SecurityException | IllegalAccessException | NoSuchFieldException e) {
someCode();
}
Dentro de Java 7 puedes definir múltiples cláusulas catch como:
catch (IllegalArgumentException | SecurityException e)
{
...
}
Si existe una jerarquía de excepciones, puede utilizar la clase base para capturar todas las subclases de excepciones. En el caso degenerado puedes detectar todas las excepciones de Java con:
try {
...
} catch (Exception e) {
someCode();
}
En un caso más común, si RepositoryException es la clase base y PathNotFoundException es una clase derivada, entonces:
try {
...
} catch (RepositoryException re) {
someCode();
} catch (Exception e) {
someCode();
}
El código anterior detectará RepositoryException y PathNotFoundException para un tipo de manejo de excepciones y todas las demás excepciones se agruparán. Desde Java 7, según la respuesta anterior de @OscarRyz:
try {
...
} catch( IOException | SQLException ex ) {
...
}