Pregunta ¿Capturas una excepción genérica en Java?


Usamos JUnit 3 en el trabajo y no hay ExpectedException anotación. Quería agregar una utilidad a nuestro código para ajustar esto:

 try {
     someCode();
     fail("some error message");
 } catch (SomeSpecificExceptionType ex) {
 }

Así que probé esto:

public static class ExpectedExceptionUtility {
  public static <T extends Exception> void checkForExpectedException(String message, ExpectedExceptionBlock<T> block) {
     try {
        block.exceptionThrowingCode();
        fail(message);
    } catch (T ex) {
    }
  }
}

Sin embargo, Java no puede usar tipos de excepción genéricos en un bloque catch, creo.

¿Cómo puedo hacer algo como esto, trabajando en torno a la limitación de Java?

¿Hay alguna manera de verificar que el ex variable es de tipo T?


32
2018-06-11 16:54


origen


Respuestas:


Podría pasar el objeto Class y verificarlo programáticamente.

public static <T extends Exception> void checkForException(String message, 
        Class<T> exceptionType, ExpectedExceptionBlock<T> block) {
    try {
       block.exceptionThrowingCode();
   } catch (Exception ex) {
       if ( exceptionType.isInstance(ex) ) {
           return;
       } else {
          throw ex;  //optional?
       }
   }
   fail(message);
}

//...
checkForException("Expected an NPE", NullPointerException.class, //...

No estoy seguro de si querrías el reestreno o no; reiniciar fallaría / error igualmente la prueba, pero semánticamente no lo haría, ya que básicamente significa "no obtuvimos la excepción que esperábamos" y eso representa un error de programación, en lugar de un error en el entorno de prueba.


27
2018-06-11 16:56



Entiendo el impulso de tratar de simplificar su idioma de excepción, pero en serio: no. Cada posible elección que se te ocurra es una cura peor que la enfermedad. Especialmente ¡Tonterías de @ExpectedException de JUnit 4! Es una solución framework demasiado inteligente, que requiere que todos aprendan cómo funciona, a diferencia de un simple código evidente de código Java normal. Peor aún, no le da ninguna forma de ajustar solo la parte de su prueba que espera arrojar la excepción, por lo que si un paso de configuración anterior arroja la misma excepción, su prueba pasará aunque su código esté roto.

Podría escribir una larga diatriba sobre esto aquí (lo siento por no tener suficiente tiempo), ya que hemos tenido una larga discusión de este problema entre los ingenieros de Java aquí en Google, y el consenso fue que ninguna de estas soluciones locas valen la pena Acostúmbrate a probar / atrapar, realmente no es tan malo.


5
2018-06-11 17:03



Los genéricos no son tipos. No son plantillas. Son comprobaciones de tipo de tiempo de compilación, en Java. Los bloques de excepciones detectan el tipo. Puede atrapar (Excepción e) o incluso atrapar (Lanzable e) y luego lanzarlo según sea necesario.


1
2018-05-25 18:47



Bueno, podrías coger Exception y Rethrow si no es una excepción esperada. Aunque la buena práctica de codificación generalmente dicta que la ruta de éxito del código no debe definirse por una excepción, entonces es posible que desee reconsiderar su diseño.


0
2018-06-11 16:59



También puede usar un IDE que admita la plantilla en vivo (como IntellJ IDEA por ejemplo ) y asignar un atajo como ee -> [tab] que inserta el try / catch / ignore para su y le permite escribir el correcto.

como este http://img80.imageshack.us/img80/433/capturadepantalla201006j.png

como este http://img641.imageshack.us/img641/6733/capturadepantalla201006w.png


0
2018-06-11 17:31



La cláusula de captura con parámetro de tipo no es posible:
http://docs.oracle.com/javase/tutorial/java/generics/restrictions.html#cannotCatch


0
2018-01-23 01:12