2009-07-08 17 views
12

A veces, solo tiene que atrapar Throwable, p. Ej. cuando se escribe una cola de despachador que despacha artículos genéricos y necesita recuperarse de cualquier error (dicho despachador registra todas las excepciones detectadas, pero en silencio, y luego la ejecución continúa en otros artículos).Mejores prácticas para capturar Throwable en Java

Una mejor práctica que puedo pensar es siempre volver a lanzar la excepción si se trata de la excepción InterruptedException, porque esto significa que alguien interrumpió mi hilo y quiere matarlo.

Otra sugerencia (que vino de un comentario, no una respuesta) es siempre volver a lanzar ThreadDeath

Cualesquiera otras mejores prácticas?

+2

'ThreadDeath' también debe volver a lanzarse, pero no debe tirarse en primer lugar. –

+0

¿Por qué un comentario, este es solo el tipo de respuesta que quería? – ripper234

Respuesta

12

Probablemente el más importante es Nunca tragar una excepción marcada. Con esto quiero decir que no hacer esto:

try { 
    ... 
} catch (IOException e) { 
} 

menos que eso es lo que se propone. A veces las personas tragan excepciones comprobadas porque no saben qué hacer con ellas o no quieren (o no pueden) contaminar su interfaz con las cláusulas "arroja excepciones".

Si usted no sabe qué hacer con él, hacer esto:

try { 
    ... 
} catch (IOException e) { 
    throw new RuntimeException(e); 
} 

el otro que viene a la mente es asegurarse de que usted se ocupa de excepciones. Leer un archivo debería tener un aspecto similar al siguiente:

FileInputStream in = null; 
try { 
    in = new FileInputStream(new File("..."));; 
    // do stuff 
} catch (IOException e) { 
    // deal with it appropriately 
} finally { 
    if (in != null) try { in.close(); } catch (IOException e) { /* swallow this one */ } 
} 
+2

+1 en el tragar nunca una excepción marcada, incluso en su 'primer pase'. Con demasiada frecuencia, estas cosas se pasan por alto y, en última instancia, se someten al control de la fuente. si tiene dudas, al menos imprima el seguimiento de la pila. – akf

+0

¡Si no puede manejarlo y no puede volver a lanzarlo, al menos imprima ese rastro de pila! Una traza de pila en el registro es de gran ayuda para diagnosticar el problema. – starblue

+1

El horror de las excepciones comprobadas ... ¿captura IOException solo para envolverlo en una excepción no verificada y NO hacer nada con eso? Por supuesto, eso es lo que tienes que hacer en Java, a menos que realmente sepas por qué recibes la Excepción. –

2

Depende de lo que esté trabajando.

Si está desarrollando una API para ser utilizada por alguien más, es mejor volver a lanzar la Excepción o envolverla en una excepción personalizada suya y lanzarla.

Considerando que si está desarrollando una aplicación de usuario final necesita manejar esta excepción y hacer lo necesario.

1

Si está escribiendo una cola de despachador, cuando la excepción vuelva a aparecer no tiene sentido hacer nada con ella además de iniciar sesión. La cola de eventos Swing tiene básicamente ese tipo de comportamiento.

Alternativamente, podría proporcionar un gancho para un "manejador de excepciones no capturadas", similar al ThreadGroup. Tenga en cuenta que el controlador puede llevar mucho tiempo y terminar retrasando a su despachador.

En lo que se refiere a InterruptedException: lo único que le importa es su ciclo de envío, que debería verificar algún estado externo para ver si debería detener el procesamiento.

+0

¿Por qué es mejor verificar un estado externo que usar InterruptedException como mecanismo de señalización? – ripper234

+0

Porque InterruptedException simplemente indica que alguien llamó a interrupt() en el hilo. Podría haber múltiples razones para hacer esto, no solo terminar la acción actual. Y si desea utilizar interrupt() para terminar el despachador, ciertamente no desea tirarlo; simplemente regrese de run() - a menos que, por supuesto, su despachador no sea lo único que está haciendo el hilo, pero incluso allí, es casi seguro que no desea tirar ciegamente. – kdgregory

2

¿Qué pasa con OutOfMemoryError (o tal vez su super clase VirtualMachineError)? No puedo imaginar que haya mucho que puedas hacer después de algo tan serio.

+1

Si el subproceso que asigna una gran cantidad de objetos pasa a capturar el OutOfMemoryError en un punto donde el elemento asignado se convierte en coleccionable de basura, la VM puede recuperarse. Si todavía se hace referencia a los objetos, entonces sí, no hay mucho que pueda hacer, excepto dejar de fumar o liberar algunos objetos. –

+0

Capturar 'VirtualMachineError' es complicado porque su programa está entonces en un estado indefinido: http://stackoverflow.com/questions/8728866/no-throw-virtualmachineerror-guarantees – Raedwald