2011-08-03 11 views
6

Encuentro la jerarquía de excepciones de Java confusa. Throwable se divide en Error y Exception, y RuntimeException hereda de Exception.fundamento detrás de la jerarquía de excepciones de Java

  1. Error es una excepción no comprobada. ¿Por qué no hereda Error de RuntimeException?

  2. Exception es una excepción de verificación. RuntimeException es una excepción sin marcar, pero hereda de Exception. ¿Esto no viola el principio de sustitución de Liskov?

no tendría más sentido si Throwable se dividieron en Exception (marcado) y RuntimeException (sin marcar), y Error heredaría de RuntimeExeption?

+2

Principalmente, creo que querían separar los términos 'Error' y' Exception'. El error significa que algo fatal sucedió. Y la excepción es alguna condición que cambia el flujo del programa, no deseado. Podría ser, luego agregaron 'RuntimeException', que está desmarcada ... – Parth

Respuesta

3

Encuentro la jerarquía de excepciones de Java confusa. Throwable se divide en Error y Excepción, y RuntimeException hereda de Exception.

A Throwable es algo que se puede utilizar para desenrollar la pila de llamadas. Esto debe incluir alguna falta VM nivel (indicado con un error) y específica algo aplicación (marcado por una excepción)

Error es una excepción no comprobada. ¿Por qué no se hereda Error de RuntimeException?

Simplemente porque los errores no son excepciones. No tendría sentido "capturar" un error. Por ej. ¿Qué harías después de atrapar un OutOfMemoryError? Los errores están destinados a indicar que algo sucedió seriamente en el nivel VM que no es necesariamente manejable por el programador

La excepción es una excepción marcada. RuntimeException es una excepción sin marcar, pero hereda de Exception. ¿Esto no viola el principio de sustitución de Liskov?

Realmente no. Lo que los implementadores intentaban decir era que siempre se DEBEN verificar las excepciones. Su código estará más limpio si todos sus métodos declaran qué tipo de aplicación/biblioteca Excepciones arrojan. RuntimeExceptions solo debe lanzarse en el caso de situaciones más generales/dinámicas como NullPointerException donde el desarrollador podría no haber codificado el caso pero es un error grave que no es exactamente algo mencionado en la especificación de la aplicación.

1

creo que es incluso mejor jerarquía

Throwable Excepción CheckedException RuntimeException error

Esta jerarquía separa excepciones y errores (como dijo @Paarth) y hace posible coger todos comprueba únicas excepciones (sin excepciones de tiempo de ejecución). Pero parece que James Gosling pensó diferente ...

0
  1. error no es una subclase de excepción, ya que no tiene la intención de coger (se produjo un error Una vez que por lo general el programa ya no se espera que funcione). Entonces, el error debería tener un lugar más alto en la jerarquía, como creo.

  2. No debe violar la sustitución de Liskov porque RuntimeException puede atraparse si lo desea, pero solo no se aplica.

2

El diseño de manejo de excepciones en los dos marcos orientados a objetos más populares (Java y .NET) se basa en la idea de que la cuestión de si se debe manejar una excepción en particular dependa principalmente de su tipo, y que los tipos de excepciones que uno querrá atrapar tendrán una relación de clase jerárquica. Creo que Java y .NET hacen las cosas de esa manera porque C++ lo hizo de esa manera, y C++ lo hizo de esa manera debido al deseo de evitar el cableado de los tipos no primitivos codificados en el lenguaje. En ausencia de un tipo de código fijo al que se puedan emitir todas las excepciones, es imposible que una declaración catch conozca cualquier cosa sobre cualquier tipo de excepción para la que no esté explícitamente preparado. Si solo tiene sentido capturar excepciones, se puede decodificar, una declaración catch podrá actuar con sensatez sobre esos tipos, y solo esos tipos, que se derivan de la declaración.

En retrospectiva, probablemente hubiera sido mejor tener las decisiones de qué excepciones se deben tomar medidas y/o resolverse mediante declaraciones particulares de catch que se determinan por algún medio que no sea la jerarquía de clases. Entre otras cosas, un solo intento de invocar un método puede fallar debido a múltiples problemas; si eso ocurre, cada catch asociado con cualquier de esos problemas debería desencadenarse, pero solo cuando todos se hayan resuelto los problemas si se reanuda la ejecución normal. Desafortunadamente, ni Java ni .NET tienen ningún mecanismo para lograr dicho comportamiento.

Con respecto al diseño de nivel superior de la jerarquía, creo que se suponía que cada tipo de excepción que podría arrojarse por un método siempre se esperaría por el código de llamada inmediata o nunca esperado por cualquier llamada código. Las excepciones de este último tipo se clasificaron en Error o RuntimeException, mientras que las del primer tipo se colocaron en otro lugar. En la práctica, la pregunta de si una excepción es esperada por el llamador de un método debe ser independiente de su lugar en la jerarquía o incluso el tipo de excepción. El hecho de que un método se declare como throws FooException no significa que el código de llamada siempre espere que se produzca la excepción. Es muy común que el código llame a un método que se declara como lanzar una excepción pero cree que las circunstancias que rodean la llamada son tales que en la práctica esa llamada en particular nunca se lanzará. Si se produce la excepción, debería comportarse como una excepción inesperada, , incluso si un contexto de ejecución externo espera detectar una excepción de ese tipo. Lamentablemente, los mecanismos de manejo de excepciones son lo que son, y no espero ninguna revisión importante.

Cuestiones relacionadas