2010-03-10 8 views

Respuesta

47

Porque cuando detecta la excepción se supone que debe manejarlo correctamente. Y no puede esperar manejar todo tipo de excepciones en su código. Además, cuando detecta todas las excepciones, puede obtener una excepción que no puede tratar y evitar que el código que está en la parte superior de la pila lo maneje correctamente.

El objetivo general es captar el tipo más específico que pueda.

+9

Por ejemplo, un java.lang.InterruptedException se eleva cuando se le pide un hilo de parar. Si se detecta e ignora, el procesamiento del hilo no puede detenerse correctamente y su código se vuelve inadecuado para ejecutarse en un hilo de trabajo. Este es un ejemplo, puede haber otros. – Pierre

+1

Soy un gran admirador de que las personas entiendan sus marcos. La razón principal por la cual este consejo es terrible es que, el 90% del tiempo, el código por el que las personas escriben el manejo de excepciones está en el límite de su API. Estoy de acuerdo en que dentro de una API, siempre debes atrapar las excepciones apropiadas, pero cuando estás en un límite de la API, captura todo lo que no mata al sistema. – coding

5

Porque realmente no sabe por qué se produjo una excepción, y varias excepciones requieren que un automóvil muy especial se maneje correctamente (si es posible), como una excepción OutOfMemoryException y excepciones de sistema de bajo nivel similares.

Por lo tanto, sólo se debe capturar las excepciones:

  • que sabe exactamente cómo tratar con él (por ejemplo FileNotFoundException más o menos)
  • cuando va a volver a subir ellos después (por ejemplo, para realizar después -a prueba de limpieza)
  • cuando se necesita transportar la excepción a otro hilo
+0

No existe la excepción OutOfMemoryException. Hay OutOfMemoryError que se encuentra bajo la jerarquía Throwable. –

+2

@EladTabak, tienes razón, por supuesto, en lo que respecta a Java. Dicho esto, la etiqueta "java" no estaba allí cuando me contestó la pregunta (ver [historial de revisiones] (http://stackoverflow.com/posts/2416316/revisions)), y el significado transmitido es sin embargo correcto - independientemente de el ambiente real. – Lucero

5

depende de lo que necesita. Si necesita manejar diferentes tipos de excepciones de diferentes maneras, entonces debe usar múltiples bloques catch y capturar tantas excepciones específicas como pueda.

Pero a veces puede necesitar manejar todas las excepciones de la misma manera. En tales casos, catch (Exception) puede estar bien. Por ejemplo:

try 
    { 
     DoSomething(); 
    } 
    catch (Exception e) 
    { 
     LogError(e); 
     ShowErrorMessage(e); // Show "unexpected error ocurred" error message for user. 
    } 
+2

Ese no es un buen patrón a seguir; el registro no debe hacerse así porque obtendrá un montón de las mismas entradas para cada "nivel" de try-catch. – Lucero

+0

Estoy de acuerdo, lo usé solo como ejemplo. Puede no ser el mejor ejemplo :) –

+1

@Lucero: yo creo que es mejor tener un marco de registro que se pueden consolidar las entradas redundantes, de asumir que lo manijas capa (golondrina) una excepción registrará ella. Además, a menos excepciones son tan numerosos que la tala de ellos varias veces plantearía un cuello de botella (en cuyo caso yo diría que * es * un problema que necesita ser arreglado) yo creo que tiene información redundante en el registro, que luego podría ser filtrada por una utilidad de visualización de registro, sería preferible a tener un registro más conciso que carece de la única información que uno necesita. – supercat

8

Solo debe detectar excepciones si puede manejarlas adecuadamente. Como no puede manejar adecuadamente todas las excepciones posibles, no debe capturarlas :-)

+8

Un problema importante con este tipo de pensamiento es que hay muchas situaciones en las que el manejo adecuado para el 99% de las excepciones que podrían botados sería informar de que algún tipo de acción no se pudo completar y seguir con su vida, pero la identificación de todos y cada uno tipo de excepción para la cual ese sería el curso de acción apropiado sería difícil si no imposible. Lástima que no hay ningún mecanismo para distinguir las excepciones de "no se pudo satisfacer la solicitud" de las excepciones de "CPU está en llamas". – supercat

+1

La CPU está en llamas probablemente cause algún tipo de 'java.lang.Error'. – yegeniy

+0

> Un error es una subclase de Throwable que indica problemas graves que una aplicación razonable no debería tratar de detectar. – yegeniy

15

Breve historia: se llama máscara de errores. Si tienes un código que no funciona bien y lanzas excepciones (o pasas una entrada mal formada a ese fragmento de código) y simplemente te ciegas mirando todas las excepciones posibles, nunca descubrirás el error y lo arreglarás.

+0

"Capturar" una excepción no significa simplemente continuar ejecutando como si no hubiera nada mal. Un bloque de "captura" es un bloque de código donde haces ** algo **. Ese ** algo **, podría ser registrar información sobre la excepción, sobre lo que estaba haciendo el usuario o el estado de la interfaz de usuario, cerrar las conexiones y archivos para que la aplicación salga con gracia y notificar al usuario lo que sucedió. ¿Cómo es esto "enmascarar" algo? – user316117

+0

@ user316117 'Exception' es la clase superior de todas las excepciones en Java. Atrapar eso significa que atrapas todos los errores posibles. ¿Cómo sabrías qué hacer en ese bloque? Si desea reaccionar a un cierto error, tome su excepción específica y trabaje con ella. No hay ningún uso práctico para detectar todas las excepciones posibles excepto para cegar los ojos (y he visto a muchos colegas haciéndolo porque quieren irse a casa al final de la jornada laboral). – dimitarvp

+0

@dimitarvp Throwable es de primera clase de todas las excepciones. Tiene dos subclase que divide excepciones en dos ramas. Uno de ellos es EXCEPCIÓN y el otro es ERROR. –

0

Esto puede ser Java específica:

A veces se tendrá que llamar a los métodos que generen excepciones controladas. Si esto está en su capa EJB/lógica de negocios, tiene 2 opciones: tomarlas o volver a lanzarlas.

La captura de clases de excepciones específicas significa que tendrá que volver a analizar sus acciones para las cuales se pueden lanzar excepciones cuando observe cómo este código maneja las excepciones. A menudo te meterás en una situación de "y si ..." y puede que te cueste un montón de esfuerzo si las excepciones se manejan correctamente.

Volver a lanzar significa que el código que llama a los EJB estará plagado de código de captura que normalmente no significará nada para la clase llamante. nótese bien. arrojar excepciones controladas de los métodos EJB significará que usted es responsable de anular manualmente cualquier transacción.

0

Además de lo recibido ninguna respuesta por @anthares:

Porque cuando se captura una excepción que se supone que manejarlo adecuadamente. Y no puede esperar manejar todo tipo de excepciones en su código. Además, cuando detecta todas las excepciones, puede obtener una excepción que no puede tratar y evitar que el código que está en la parte superior de la pila lo maneje correctamente.

El objetivo general es captar el tipo más específico que pueda.

catch(Exception) es una mala práctica porque atrapa todos los RuntimeException (excepción no verificada) también.

0

¡Pero a veces está bien! Por ejemplo, si tienes un código que hace algo 'extra', que realmente no te importa, y no quieres que explote tu aplicación. Por ejemplo, trabajé recientemente en una gran aplicación en la que nuestros socios comerciales querían que una determinada transacción diaria se resumiera en un nuevo archivo de registro. Explicaron que el registro no era tan importante para ellos, y que no calificaba como un requisito. Era algo extra que les ayudaría a entender los datos que se procesaban. No lo necesitaban, porque podían obtener la información en otro lugar. Así que ese es un caso raro en el que está perfectamente bien atrapar y tragar excepciones.

También trabajé en una empresa donde se capturaron todos los Throwables y luego se volvieron a montar en una RuntimeException personalizada. No recomendaría este enfoque, solo señalaría que ya está hecho.

0

Encontré dos usos aceptables de captura (Excepción): - En el nivel superior de la aplicación (justo antes de regresar al usuario). De esa manera puede proporcionar un mensaje adecuado. - Utilizándolo para enmascarar las excepciones de bajo nivel a las de negocios.

El primer caso es auto explicativa-, pero vamos a desarrollar la segunda:

Haciendo:

try { 
    xxxx 
} catch(Exception e) { 
    logger.error("Error XXX",e) 
} 

es enmascaramiento de errores como @dimitarvp dijo.

Pero

try { 
    xxxx 
} catch(Exception e) { 
    throw new BussinessException("Error doing operation XXX",e) 
} 

Es una cosa diferente. De esta forma, no ignorarás los errores y te esconderás debajo de la alfombra. Está proporcionando una excepción de alto nivel con un mensaje más explicativo para capas de aplicaciones más altas.

Siempre es importante que dos gestionen la excepción en su capa correcta. Si deja escalar una excepción de bajo nivel a una capa empresarial alta, es prácticamente imposible que la capa superior pueda administrarla bien. En esos casos, prefiero enmascarar las excepciones de niveles bajos con una de negocios que proporciona un mejor contexto y mensaje y que también tiene la excepción original para poder ir a los detalles.

Aún así, si puede detectar excepciones más concretas y puede proporcionar un mejor tratamiento para ellas, debe hacerlo.

Si en un bloque de código puede obtener una excepción SQLException y una excepción de red, debe capturarlas y proporcionar los mensajes y el tratamiento adecuados para cada una de ellas. Pero si al final del bloque try/catch tiene un mapeo de excepción con una BussinessException, está bien para mí. De hecho, considero adecuado que las capas de servicio superior solo arrojen excepciones comerciales (con detalles en el interior).

Cuestiones relacionadas