try todas tipos solo salida propagacion personalizadas number lista letras las excepciones entrada catch java exception

todas - Estilo Java: manejo adecuado de excepciones



todas las excepciones en java (5)

Me sigo atorando conceptualmente al decidir una estructura de manejo de excepciones para mi proyecto.

Supongamos que tiene, por ejemplo:

public abstract class Data { public abstract String read(); }

Y dos subclases FileData, que lee sus datos de un archivo especificado, y StaticData, que solo devuelve algunos datos constantes predefinidos.

Ahora, al leer el archivo, se puede lanzar una IOException en FileData, pero StaticData nunca lanzará. La mayoría de las guías de estilo recomiendan propagar una excepción en la pila de llamadas hasta que haya una cantidad suficiente de contexto disponible para manejarla de manera efectiva.

Pero realmente no quiero agregar una cláusula throws al método abstracto de lectura (). ¿Por qué? Debido a que Data y la complicada maquinaria que lo usa no saben nada sobre los archivos, solo conocen los datos. Además, puede haber otras subclases de datos (y más de ellas) que nunca arrojan excepciones y entregan datos de manera impecable.

Por otro lado, la IOException es necesaria, ya que si el disco es ilegible (o algo así) se debe lanzar un error. Así que la única salida que veo es atrapar la IOException y lanzar RuntimeException en su lugar.

¿Es esta la filosofía correcta?


Si no declaras explícitamente que read() puede lanzar una excepción, entonces sorprenderás a los desarrolladores cuando lo haga.

En su caso particular, captaría las excepciones subyacentes y las volvería a lanzar como una nueva clase de excepción DataException o DataReadException .


Tienes razón.

La excepción debe estar en el mismo nivel de abstracción donde se usa. Esta es la razón por la cual java 1.4 Throwable admite cadenas de excepción. No tiene sentido lanzar FileNotFoundException para un servicio que usa una base de datos, por ejemplo, o para un servicio que es "store" agnóstico.

Podría ser así:

public abstract class Data { public abstract String read() throws DataUnavailableException; } class DataFile extends Data { public String read() throws DataUnavailableException { if( !this.file.exits() ) { throw new DataUnavailableException( "Cannot read from ", file ); } try { .... } catch( IOException ioe ) { throw new DataUnavailableException( ioe ); } finally { ... } } class DataMemory extends Data { public String read() { // Everything is performed in memory. No exception expected. } } class DataWebService extends Data { public string read() throws DataUnavailableException { // connect to some internet service try { ... } catch( UnknownHostException uhe ) { throw new DataUnavailableException( uhe ); } } }

Tenga en cuenta que si programa con herencia en mente, debe diseñar cuidadosamente los escenarios específicos y probar las implementaciones con esos escenarios. Obviamente, si es más difícil codificar una biblioteca de propósito general, porque no sabe cómo se va a utilizar. Pero la mayoría de las veces las aplicaciones están restringidas a un dominio específico.

¿Debería su nueva excepción ser Runtime o Checked? Depende, la regla general es lanzar Runtime para los errores de programación y verificar las condiciones recuperables.

Si la excepción se puede evitar programando correctamente (como NullPointerException o IndexOutOfBounds), use Runtime

Si la excepción se debe a algún recurso externo fuera del control del programador (la red está inactiva, por ejemplo) Y hay algo que se podría hacer (mostrar un mensaje de reintento en 5 minutos o algo así), entonces se debe usar una excepción marcada .

Si la excepción está fuera del control del programador, pero NADA se puede hacer, podría usar una RuntimeException. Por ejemplo, se supone que debe escribir en un archivo, pero el archivo fue eliminado y no puede volver a crearlo o volver a intentarlo, entonces el programa debería fallar (no hay nada que pueda hacer al respecto) más probable con un Runtime.

Vea estos dos elementos de Effective Java:

  • Use excepciones marcadas para condiciones recuperables y excepciones de tiempo de ejecución para errores de programación
  • Lanzar excepciones apropiadas a la abstracción

Espero que esto ayude.


Tire la IOException envuelta en un tipo de excepción que sea apropiado para la clase " Data ". El hecho es que el método de read no siempre será capaz de proporcionar los datos, y probablemente debería indicar por qué. La excepción de RuntimeException puede extender RuntimeException y, por lo tanto, no es necesario declararla (aunque debe documentarse adecuadamente).


Utilice las Excepciones de tiempo de ejecución, combinadas con un catch-all explosivo en la parte superior. Da un poco de miedo al principio, pero mejora una vez que te acostumbras.

En mis aplicaciones web, todo lo que se lanza es Runtime. Casi no hay cláusulas "throws", y solo tengo catchblocks en lugares en los que realmente puedo (o deseo) manejar la excepción. En el nivel más alto, hay una captura Throwable que presenta una página de error técnico y escribe una entrada de registro.

Un programa de correo Log4J me envía la entrada de registro y 10 entradas de registro que lo preceden. Entonces, cuando el cliente llama, normalmente ya sé que hubo un problema.

Con las pruebas adecuadas (de la unidad) y la programación limpia, la limpieza y la legibilidad mejoradas superan la pérdida de excepciones comprobadas en cualquier momento.


Debe declarar algún tipo de excepción en el método abstracto de lectura (). La clase abstracta declara efectivamente una interfaz, y usted ya sabe por sus dos subclases concretas que una implementación puede no ser exitosa debido a una condición de excepción.

Por lo tanto, declarar que se arrojó alguna excepción en el método abstracto Data.read () es completamente correcto. No tengas la tentación de declarar simplemente que lanza IOException, ya que no debería estar vinculado a las implementaciones específicas (de lo contrario, tendrías que declarar que también podría lanzar SQLException en caso de que alguna vez decidas tener una base de datos). la lectura de la subclase, SAXException en caso de que alguna vez tenga un lector basado en XML (que use SAX), y así sucesivamente). Necesitará una excepción personalizada propia que capte adecuadamente esto en el nivel abstracto, algo así como la DataException recomendada anteriormente, o potencialmente reutilizar una excepción personalizada existente del mismo paquete si tiene sentido.