¿Puedo detectar varias excepciones de Java en la misma cláusula de captura?

Resuelto froadie asked hace 14 años • 11 respuestas

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?

froadie avatar Aug 17 '10 01:08 froadie
Aceptado

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 ExceptionAy ExceptionBen el mismo bloque si ExceptionBse 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.

OscarRyz avatar Aug 16 '2010 18:08 OscarRyz

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();
}
user454322 avatar Aug 28 '2012 09:08 user454322

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();
}
duffymo avatar Aug 16 '2010 18:08 duffymo

Dentro de Java 7 puedes definir múltiples cláusulas catch como:

catch (IllegalArgumentException | SecurityException e)
{
    ...
}
crusam avatar Aug 16 '2010 18:08 crusam

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 ) { 
  ...
}
Michael Shopsin avatar Aug 16 '2010 18:08 Michael Shopsin