2011-01-17 21 views
13

He oído que atrapar NullPointerException es una mala práctica, y creo que es sensato. Permitir que el NullPointerException se propague a la parte superior permitiría la detección de un problema. Pero muchas veces he visto a muchos de mis amigos capturar Exception directamente para que no tengan que preocuparse por los diferentes tipos de excepciones que pueden ocurrir en el código anterior. ¿Es esta una buena practica? ¿Cuáles son los otros tipos de excepciones que mejor se dejan sin controlar? Y además tiene sentido para mí manejar NullPointerException sobre un código específico donde estamos seguros del origen de la excepción. Entonces, ¿cuándo se deben manejar las excepciones y cuándo no se deben manejar? ¿Y cuál sería la posible lista de excepción que es mejor dejar sin manejar?Si la captura de la excepción del puntero nulo no es una buena práctica, ¿la excepción de captura es buena?

+3

"' He oído que atrapar NullPointerException es una mala práctica, y creo que es sensato. Dejar que la NullPointerException se propague a la parte superior permitiría la detección de que algo va mal "" no tiene mucho sentido para mí . ¿No estás confundiendo 'atrapar' con 'tragar'? – leonbloy

+2

No hay nada de malo en atrapar 'NullPointerException' y hacer algo con él. Esto aplica para cualquier excepción. La idea general es capturar las excepciones que se pueden tratar, y no atrapar (dejar pasar) las que no se pueden manejar. Entonces tengo que estar en desacuerdo con lo que has escuchado. –

Respuesta

20

El manejo de excepciones de Pokemon es malo. Especialmente, si es un bloque vacío y simplemente los tragas. Tiene excepciones escritas específicamente por el hecho de que realmente se refieren a cosas específicas en contextos específicos (esencialmente le están diciendo lo que salió mal). Así que al tomar Exception está diciendo que no le importan cuáles son esas excepciones y que no le importa lo que sucedió. Esto probablemente no es lo que quieres.

En general, cuando la captura de excepciones siguen estas reglas:

  • ¿Tiene sentido para manejar la excepción a este nivel? Si es así, entonces maneja. Si no, entonces propague.
  • En relación con la primera regla, "manejo" también puede significar captura, envoltura y re-lanzamiento. Esta es una forma de evitar la fuga de abstracción, de modo que los llamantes de su método no tengan que saber acerca de la implementación subyacente.
  • Un bloqueo de catch vacío no significa que haya manejado la excepción. Eso se llama "tragar"; como mínimo, desea registrar la excepción. A veces, una excepción que sucede es en realidad parte del flujo lógico de su código, por lo que es posible que desee hacer algo especial (pero esto es, perdone el juego de palabras, la excepción en lugar de la regla. Es mejor verificar las situaciones que causan excepciones). en lugar de incorporarlos al flujo lógico de tu código).

Puede verificar fácilmente la existencia de un valor nulo en el código, por lo que no es necesario capturar explícitamente una excepción de puntero nulo. No tiene sentido dejar que suceda NullPointerException (y es una mala práctica). Incluso si tiene un código que arroja un NullPointerException, y es un código que no controla y no puede reparar, debe determinar los parámetros de entrada que causan el NullPointerException y probarlos específicamente.

Otra excepción que no debe detectar es IllegalArgumentException. Esta excepción significa que ha pasado un argumento que no tiene sentido. En lugar de detectar esta excepción, debe probar explícitamente sus parámetros de entrada para asegurarse de que están en buen estado y que no pueden causar un IllegalArgumentException.

+12

¿Qué es "control de excepciones Pokemon"? –

+25

catch (Exception ex) {para cuando quiera atraparlos a todos. –

+0

"Manejo de excepciones de Pokemon": Gotta Catch 'Em All: D – tkr

5

Solo debe detectar una excepción si puede agregar algún valor al hacerlo. De lo contrario, debe dejar que pase a la persona que llama.

NullPointerException es generalmente el resultado de un error en su código. ¿Cómo se puede solucionar esto con sensatez en un bloque catch?

No molestarse en las excepciones no es una buena práctica.

0

si tiene una manera elegante de manejar su excepción, es útil atraparla, si no es de esperar que la persona que llama tenga una buena manera de manejarla.

+1

Si no, eventualmente, la excepción puede registrarse. –

1

La regla principal sobre la captura de excepciones es que debe saber por qué lo hace. La clase de excepción se detecta en los casos en que el programador quiere hacer un procesamiento genérico de errores y realmente no le importa qué pasó exactamente, lo principal es que algo salió mal. En ese caso, él puede decidir deshacer la transacción o hacer una limpieza. Si está atrapando una excepción específica intente aplicar la misma regla. Yo sé exactamente por qué estás haciendo eso, entonces es para hacer eso. Pero es muy raro que alguien quiera hacer algo realmente especial en caso de NPE.

8

La 'razón' por la que la captura de NullPointerException se considera una mala práctica no se debe a que se supone que debe dejarla burbujear cuando algo sale mal. Decir cualquier excepción es 'mejor dejado sin manejar', basado únicamente en su tipo, parece una mala idea.

Una NPE se considera el resultado de un error de programación. Un programa estrictamente correcto nunca debe generar uno. La razón por la que se ve atrapado es malo, generalmente significa que el código arrojó uno, y el programador decidió simplemente atraparlo y taparlo, ¡en lugar de corregir el código roto que lo causó en primer lugar!

Si, por ejemplo, que se acoplaron por razones de negocios a una API que tiene un error dentro y de vez en cuando lanza un puntero nulo, sería perfectamente legítimo para cogerlo, hacer algo al respecto/informar al usuario con una mejor mensaje. Permitir que 'null' pegue en la interfaz de usuario solo porque alguien dijo "Capturar la excepción del puntero nulo es malo" no tendría sentido.

La captura java.lang.Exception puede ser legítima en casos específicos, pero generalmente "soy flojo" no es uno de ellos. :) Por ejemplo, si está implementando una API y quiere asegurarse de que no salga ninguna excepción que no esté en la especificación, puede atrapar Excepción y envolverla en alguna excepción de aplicación que haya definido.

3

En general, las únicas ocasiones en que debería detectar una excepción es si puede manejarlo de alguna manera significativa. Si no puede, simplemente debe dejarlo burbujear hasta la parte superior y finalizar el proceso. Por ejemplo, ¿podría recuperar de alguna manera significativa desde una NullPointerException o error de E/S? Yo creo que no.

Mis reglas para el manejo de excepciones:

  • En general, no debe quedar atrapado excepciones, a menos que pueda manejarlos de una manera significativa.
  • Captura excepciones en los límites de proceso/máquina, registra la excepción detectada junto con cualquier contexto disponible para ti y vuelve a lanzarla. Si la excepción es una excepción personalizada, puede envolverla en una excepción de un tipo conocido/útil para el proceso de invocación y arrojar eso.
  • También puede detectar excepciones en un nivel bajo, donde tiene el mayor contexto de tiempo de ejecución disponible, registrar la excepción y el contexto asociado, luego volver a lanzar la excepción.
  • Al reiniciar, use throw ; en lugar de throw caughtException ;. El uso de la sintaxis anterior conserva el seguimiento de la pila original; el uso de la última sintaxis crea una nueva traza de pila, que comienza con throw caughtException ; - pierde todo el contexto y la pila de llamadas hasta el punto en el que se capturó la excepción.
  • Si lo desea, puede detectar excepciones en un nivel alto y terminar el proceso con gracia, registrando la información de excepción para ayudar a depurar y corregir el problema subyacente.

No utilice excepciones como mecanismo de control de flujo (si es posible). Se supone que las excepciones son, bueno, de naturaleza excepcional.Más bien, de forma preventiva, haga cumplir el final del contrato de la persona que llama (condiciones previas) para cualquier método que invoque.

Ver el libro de Bertrand Meyers, Object Oriented Software Construction, 2nd ed. para obtener más información.

+1

En respuesta a "When Reithrowing": en Java no puede "throw;", tiene que "throw caughtException;" y tú no pierdes el rastro de la pila cuando lo haces. – hjhill

Cuestiones relacionadas