2011-10-31 25 views
12

¿Por qué se desaconseja lanzar una excepción genérica (java.lang.Exception), cuando suele ser suficiente para manejar la mayoría de las fallas condicionales dentro de un método? Entiendo que si un método arroja múltiples tipos de excepciones, arrojar subclases específicas de una excepción podría aclarar un poco el manejo, pero en un caso general de falla/éxito, creo que Exception es más que adecuado.Lanzar Excepción genérica desalentado?

+0

posible duplicado de [Mejores prácticas para la gestión de excepciones en Java o C#] (http://stackoverflow.com/questions/409563/best-practices-for-exception-management-in-java-or-c-sharp) –

Respuesta

20

El problema es que Exception también es la superclase de RuntimeException, que abarca algunas cosas que no deben ser capturado, ya que indica un problema con la programación en lugar de un excepcional condición que surge del contexto. No desea capturar una BufferOverflowException o UnsupportedOperationException en circunstancias normales. Además, lanzar tipos de excepciones por separado le da al código de llamada el control sobre cómo manejar cada uno. El texto repetitivo se reduce en Java 7 con la nueva característica de varias capturas.

+1

Ese es otro problema importante, +1. –

+0

@MarkPeters Aunque rara vez digo "nunca", ya que creo que incluso el peor antipatrón puede ser la respuesta correcta en situaciones contorsionadas, lo mejor es tener cuidado con las excepciones. A veces tendrán que ser manejados por código que no escribiste y terminarás filtrando abstracciones por toda la tienda. Entonces, por supuesto, hay quienes atrapan 'Throwable' como si no fuera gran cosa: D –

+0

+1 - Muy buen punto en verdad. – DerMike

5

Si arroja excepciones más específicas, eso no impide que ningún código de llamada maneje todas ellas en un bloque catch Exception. Ser más específico es más documentación sobre qué tipo de errores ocurren, lo que hace que sea más fácil para los programadores tratarlos por separado.

Además, al lanzar "Excepción" en sí mismo, básicamente está diciendo a quienes llaman su código que no pueden descartar ninguna clase de excepción. Un IOException pudieran ocurrir, como lo haría un NumberFormatException, etc.

1

En general, desea saber qué sucedió en su aplicación y solo detectar excepciones específicas y dejar que el programa falle (o ir más alto en el orden de ejecución) cuando obtiene la excepción que no se dirige específicamente. La excepción de captura los detectará a todos y, en algunos casos, no sabría que su programa está fallando.

3

Como siempre: Depende.

Creo que hay una diferencia entre la API que expone a los demás. Eso puede vivir por un tiempo. En ese caso, no sabe qué es lo que la persona que llama considera mejor para su caso.

Por otro lado, siempre hay un código que usa internamente solo para usted. De lo que podría ser suficiente lanzar una excepción genérica. Pero recuerde que es posible que desee cambiar el manejo de excepciones más adelante. Eso será más difícil cuando todos los casos de error se destruyan juntos.

0

Dittos to GH. Hubiera usado "excepción de puntero nulo" y "excepción de falta de memoria" como ejemplos más obvios del tipo de excepciones que probablemente no vea para atrapar en el mismo bloque con sus verdaderas excepciones de aplicación.

También agregaría que vale la pena realizar un pequeño esfuerzo para una futura capacidad de expansión. Si lanzas Excepciones genéricas por todas partes y luego decides que debes detectar algunas excepciones y otras no, puede ser una gran molestia volver atrás y cambiarlas todas. Pero si solo creas las excepciones que necesitas a medida que avanzas, no es un gran problema. Crear una nueva clase de excepción que solo acepta un constructor con un mensaje toma, ¿qué, 5 líneas de código? Es una buena inversión para el futuro.

Como muchas cosas en la programación, se trata de qué tan lejos llegar. Normalmente creo una "BadInputException" bastante genérica en casi todos los proyectos en los que trabajo, y la lanzo en cualquier momento que las entradas de usuario fallen los criterios de validación. Entonces puedo capturar BadInputException y lanzar el mensaje en la pantalla. Si creo una clase compleja que lanza excepciones para datos incoherentes y ese tipo de cosas, generalmente creo una clase de excepción para él. Como si creara una clase "TalkToDatabase", crearé una "TalkToDatabaseException". (Tal vez más que eso si hay múltiples tipos de excepciones que sé que quiero atrapar, pero al menos una.)

Y, por cierto, no sé si estás pensando en esto, pero me gustaría desaprobar el examen del texto de un mensaje de error para determinar el tipo de error. He visto programas en los que lanzar excepciones genéricas por todo el lugar, y luego en los bloques de captura tienen un código como

// Very bad idea! Don't do this! 
catch (Exception ex) 
{ 
    if (ex.getMessage().equals("Invalid foo")) 
    ... handle bad foo ... 
    else if (ex.getMessage().equals("Plugh is over maximum")) 
    ... handle bad plugh ... 
    ... etc ... 
} 

Sería mucho mejor simplemente hacer excepciones separadas para estos casos. El procesamiento no solo será mucho más eficiente, ¿pero supongamos que haces lo anterior y alguien viene después y decide cambiar el mensaje a "Foo no es válido"? El programa aún se compilará, pero no funcionará correctamente.

Cuestiones relacionadas