Pregunta ¿Puedo capturar múltiples excepciones de Java en la misma cláusula catch?


En Java, quiero hacer algo como esto:

try {
    ...     
} catch (IllegalArgumentException, SecurityException, 
       IllegalAccessException, NoSuchFieldException e) {
   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?


559
2017-08-16 18:07


origen


Respuestas:


Esto es posible desde Java 7. La sintaxis para el bloque try-catch es:

try { 
  ...
} catch (IOException | SQLException ex) { 
  ...
}

Antes de Java 7, esto no era posible. Sin embargo, recuerde que si todas las excepciones pertenecen a la misma jerarquía de clases, simplemente puede capturar ese tipo de excepción base. La única otra forma es atrapar cada excepción en su propio bloque catch.

Editar: Tenga en cuenta que en Java 7, no puede detectar tanto ExceptionA como ExceptionB en el mismo bloque si ExceptionB se hereda, directa o indirectamente, de ExceptionA. El compilador se quejará: The exception ExceptionB is already caught by the alternative ExceptionA.


918
2017-08-16 18:11



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();
}

98
2017-08-28 09:15



Dentro de Java 7 puedes definir varias cláusulas catch como:

catch (IllegalArgumentException | SecurityException e)
{
    ...
}

23
2017-08-16 18:12



No, uno por cliente

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 esa podría no ser la mejor práctica. Solo debería detectar una excepción cuando tenga una estrategia para manejarla realmente, y el registro y reintroducción no es "manejarlo". Si no cuenta con una acción correctiva, es mejor agregarla a la firma del método y dejarla fluir a alguien que pueda manejar la situación.


14
2017-08-16 18:09



Si hay una jerarquía de excepciones, puede usar la clase base para capturar todas las subclases de excepciones. En el caso degenerado puedes atrapar todas Excepciones 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 capturará RepositoryException y PathNotFoundException para un tipo de manejo de excepciones y todas las demás excepciones se agrupan juntas. Desde Java 7, según la respuesta de @SarrayRyz anterior:

try { 
  ...
} catch( IOException | SQLException ex ) { 
  ...
}

13
2017-08-16 18:12



Una alternativa más limpia (pero menos detallada, y quizás no tan preferida) a la respuesta del usuario454322 en Java 6 (es decir, Android) sería atrapar todo Exceptions y volver a tirar RuntimeExceptions. Esto no funcionaría si estás planeando capturar otros tipos de excepciones en la parte superior de la pila (a menos que también los vuelvas a lanzar), pero atraparán efectivamente a todos comprobado excepciones

Por ejemplo:

try {
    // CODE THAT THROWS EXCEPTION
} catch (Exception e) {
    if (e instanceof RuntimeException) {
        // this exception was not expected, so re-throw it
        throw e;
    } else {
        // YOUR CODE FOR ALL CHECKED EXCEPTIONS
    } 
}

Dicho esto, para verbosidad, podría ser mejor establecer un valor booleano u otra variable y, en base a eso, ejecutar algún código después del bloque try-catch.


8
2017-10-18 21:04



En pre-7, ¿qué tal:

  Boolean   caught = true;
  Exception e;
  try {
     ...
     caught = false;
  } catch (TransformerException te) {
     e = te;
  } catch (SocketException se) {
     e = se;
  } catch (IOException ie) {
     e = ie;
  }
  if (caught) {
     someCode(); // You can reference Exception e here.
  }

3
2018-02-16 18:08



Captura la excepción que resulta ser una clase principal en la jerarquía de excepciones. Esto es, por supuesto, una mala práctica. En su caso, la excepción principal común pasa a ser la clase Excepción, y capturar cualquier excepción que sea una instancia de Excepción, es de hecho una mala práctica: excepciones como NullPointerException suelen ser errores de programación y generalmente deben resolverse comprobando valores nulos.


0
2017-08-16 18:10



Sí. Aquí está la manera de usar el separador de tuberías (|),

try
{
    catch(IllegalArgumentException | SecurityException | IllegalAccessException | NoSuchFieldException e)
    {
       someCode();
    }
}

0
2017-07-31 10:51