Cuándo atrapar java.lang.Error?

votos
101

¿En qué situaciones debería uno atrapar java.lang.Erroruna aplicación?

Publicado el 09/12/2008 a las 14:56
fuente por usuario
En otros idiomas...                            


16 respuestas

votos
87

En general, nunca. Sin embargo, a veces es necesario atrapar errores específicos.

Si está escribiendo código marco-ish (cargando clases de terceros), podría ser conveniente detectar LinkageErrors (no se encontró def de clase, enlace insatisfecho, cambio de clase incompatible). También he visto algunos códigos estúpidos de terceros arrojando subcauses de Errores, por lo que también tendrás que manejarlos.

Por cierto, no estoy seguro de que no sea posible recuperarme de OutOfMemory.

Respondida el 09/12/2008 a las 15:12
fuente por usuario

votos
46

Nunca. Nunca puede estar seguro de que la aplicación puede ejecutar la siguiente línea de código. Si obtienes una OutOfMemoryError, no tienes garantía de que puedas hacer algo confiablemente . Captura RuntimeException y verifica excepciones, pero nunca errores.

http://pmd.sourceforge.net/rules/strictexception.html

Respondida el 09/12/2008 a las 15:00
fuente por usuario

votos
16

En general, siempre debe atrapar java.lang.Errory escribir en un registro o mostrarlo al usuario. Trabajo en apoyo y veo a diario que los programadores no pueden decir qué sucedió en un programa.

Si tiene un hilo daemon, entonces debe evitar que se termine. En otros casos, su aplicación funcionará correctamente.

Solo deberías atrapar java.lang.Erroral más alto nivel.

Si observa la lista de errores verá que la mayoría se puede manejar. Por ejemplo, ZipErrorocurre al leer archivos zip corruptos.

Los errores más comunes son OutOfMemoryErrory NoClassDefFoundError, que en la mayoría de los casos son problemas de tiempo de ejecución.

Por ejemplo:

int length = Integer.parseInt(xyz);
byte[] buffer = new byte[length];

puede producir OutOfMemoryErrorpero es un problema de tiempo de ejecución y no hay razón para finalizar su programa.

NoClassDefFoundErrorocurre principalmente si una biblioteca no está presente o si trabaja con otra versión de Java. Si es una parte opcional de su programa, entonces no debe finalizar su programa.

Puedo dar muchos más ejemplos de por qué es una buena idea atrapar Throwableen el nivel superior y producir un mensaje de error útil.

Respondida el 05/03/2009 a las 13:29
fuente por usuario

votos
14

En el entorno multiproceso, lo más frecuente es que quieras atraparlo. Cuando lo captures, lo registras y finalizas toda la aplicación. Si no haces eso, algún hilo que pueda estar haciendo una parte crucial estaría muerto, y el resto de la aplicación pensaría que todo es normal. Fuera de eso, muchas situaciones no deseadas pueden suceder. El problema más pequeño es que no podrá encontrar fácilmente la raíz del problema, si otros hilos comienzan a arrojar algunas excepciones debido a que un hilo no funciona.

Por ejemplo, generalmente el bucle debería ser:

try {
   while (shouldRun()) {
       doSomething();
   }
}
catch (Throwable t) {
   log(t);
   stop();
   System.exit(1);
}

Incluso en algunos casos, es posible que desee manejar diferentes errores de forma diferente, por ejemplo, en OutOfMemoryError podrá cerrar la aplicación regularmente (incluso tal vez liberar algo de memoria, y continuar), en algunos otros, no hay mucho que pueda hacer.

Respondida el 07/03/2009 a las 17:39
fuente por usuario

votos
7

Muy raramente.

Diría solo en el nivel superior de un hilo para INTENTAR emitir un mensaje con el motivo de la muerte de un hilo.

Si está en un marco que hace este tipo de cosas para usted, déjelo en el marco.

Respondida el 09/12/2008 a las 15:15
fuente por usuario

votos
6

Si estás lo suficientemente loco como para crear un nuevo marco de pruebas de unidades, es probable que tu corredor de pruebas tenga que atrapar java.lang.AssertionError arrojado por cualquier caso de prueba.

De lo contrario, vea otras respuestas.

Respondida el 10/12/2008 a las 21:44
fuente por usuario

votos
6

Por lo Errorgeneral, no se debe atrapar , ya que indica una condición anormal que nunca debería ocurrir .

De la especificación de la API de Java para la Errorclase:

Una Errorsubclase de Throwable eso indica problemas graves que una aplicación razonable no debería tratar de detectar. La mayoría de esos errores son condiciones anormales. [...]

No se requiere un método para declarar en su cláusula throws ninguna subclase de Error que pueda lanzarse durante la ejecución del método pero que no se capture, ya que estos errores son condiciones anormales que nunca deberían ocurrir.

Como se menciona en la especificación, Errorsolo se arroja en circunstancias que sí lo son. Las posibilidades son que, cuando Errorocurre, hay muy poco que la aplicación puede hacer, y en algunas circunstancias, la Máquina Virtual de Java en sí puede estar en un estado inestable (como VirtualMachineError)

Aunque una Errorsubclase es una de Throwableellas, significa que puede ser atrapada por una try-catchcláusula, pero probablemente no sea realmente necesaria, ya que la aplicación se encontrará en un estado anormal cuando Errorla JVM arroje una.

También hay una breve sección sobre este tema en la Sección 11.5 Jerarquía de excepciones de la Especificación del lenguaje Java, 2da Edición .

Respondida el 09/12/2008 a las 15:18
fuente por usuario

votos
6

Casi nunca. Los errores están diseñados para ser problemas que las aplicaciones generalmente no pueden hacer nada al respecto. La única excepción podría ser manejar la presentación del error, pero incluso eso podría no ir según lo previsto dependiendo del error.

Respondida el 09/12/2008 a las 14:59
fuente por usuario

votos
5

Y hay un par de otros casos en los que si detecta un error, debe volver a lanzarlo . Por ejemplo, ThreadDeath nunca debe ser capturado, puede causar un gran problema si lo atrapa en un entorno contenido (por ejemplo, un servidor de aplicaciones):

Una aplicación debe capturar instancias de esta clase solo si debe limpiar después de terminar de forma asincrónica. Si ThreadDeath es capturado por un método, es importante volver a tirarlo para que el hilo realmente muera.

Respondida el 09/12/2008 a las 15:09
fuente por usuario

votos
4

Muy, muy raramente.

Lo hice solo por un caso conocido muy específico. Por ejemplo, java.lang.UnsatisfiedLinkError podría lanzarse si dos independent ClassLoader cargan la misma DLL. (Estoy de acuerdo en que debería mover el JAR a un cargador de clases compartido)

Pero el caso más común es que necesitó iniciar sesión para saber qué sucedió cuando el usuario vino a quejarse. Quiere un mensaje o una ventana emergente para el usuario, en lugar de silenciarla.

Incluso un programador en C / C ++, aparece un error y dice algo que las personas no entienden antes de salir (por ejemplo, falla de la memoria).

Respondida el 09/12/2008 a las 15:28
fuente por usuario

votos
3

que es bastante práctico para coger java.lang.AssertionError en un entorno de prueba ...

Respondida el 27/11/2013 a las 02:53
fuente por usuario

votos
3

En una aplicación para Android que estoy poniendo un java.lang.VerifyError . Una biblioteca que estoy usando no funciona en dispositivos con una versión antigua del sistema operativo y el código de la biblioteca generará un error de este tipo. Podría, por supuesto, evitar el error mediante la comprobación de la versión del sistema operativo en tiempo de ejecución, pero:

  • El SDK soportado más antiguo puede cambiar en el futuro para la biblioteca específica
  • El bloque de error try-catch es parte de una más grande caer de nuevo mecanismo. Algunos dispositivos específicos, aunque se supone que deben apoyar a la biblioteca, que generan excepciones. Cojo VerifyError y todas las excepciones de usar una solución de repliegue.
Respondida el 14/03/2013 a las 07:17
fuente por usuario

votos
2

Lo ideal sería que no hay que manejar / errores de captura. Pero puede haber casos en los que tenemos que hacer, basado en el requisito del marco o de la aplicación. Decir que tengo un demonio analizador XML que implementa DOM analizador que consume más memoria. Si hay un requisito como el hilo Analizador no debe murió cuando se pone OutOfMemoryError , sino que debe manejarlo y enviar un mensaje / correo al administrador de la aplicación / marco.

Respondida el 05/05/2014 a las 19:22
fuente por usuario

votos
1

Hay un error cuando la JVM no más está funcionando como se esperaba, o está a punto de. Si se coge un error, no hay garantía de que el bloque catch se ejecutará, y menos aún que se ejecutará hasta el final.

También dependerá del equipo que ejecuta, el estado actual de la memoria, así que no hay manera de probar, tratar de hacer lo mejor posible. Sólo tendrá un resultado hasardous.

También rebajar la legibilidad del código.

Respondida el 23/04/2013 a las 17:50
fuente por usuario

votos
1

Puede ser que sea apropiada para atrapar error dentro de las pruebas de unidad que se comprueba una afirmación. Si alguien desactiva afirmaciones o de otra manera elimina la afirmación de que usted quiere saber

Respondida el 19/08/2012 a las 21:35
fuente por usuario

votos
1

Lo ideal sería que nunca debemos coger un error en nuestra aplicación Java, ya que es una condición anormal. La aplicación estaría en estado anormal y podría resultar en carshing o dar algún resultado seriamente mal.

Respondida el 26/01/2011 a las 07:23
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more