Cómo manejar las excepciones de Java de la manera correcta

Cómo manejar las excepciones de Java de la manera correcta

Como novato en programación, el concepto de manejo de excepciones puede ser difícil de entender. No es que el concepto en sí sea difícil, pero la terminología puede hacer que parezca más avanzado de lo que es. Y es una característica tan poderosa que es propensa al uso indebido y al abuso.





En este artículo, aprenderá qué son las excepciones, por qué son importantes, cómo usarlas y los errores comunes que debe evitar. La mayoría de los lenguajes modernos tienen algún tipo de manejo de excepciones, por lo que si alguna vez pasa de Java, puede llevarse la mayoría de estos consejos.





Comprensión de las excepciones de Java

En Java, un excepción es un objeto que indica que ocurrió algo anormal (o 'excepcional') durante la ejecución de su aplicación. Tales excepciones son arrojado , lo que básicamente significa que se crea un objeto de excepción (similar a cómo se 'generan' los errores).





La belleza es que puedes captura excepciones lanzadas, lo que le permite lidiar con la condición anormal y permitir que su aplicación continúe ejecutándose como si nada hubiera salido mal. Por ejemplo, mientras que un puntero nulo en C puede bloquear su aplicación, Java le permite lanzar y atrapar

|_+_|

s antes de que una variable nula tenga la posibilidad de provocar un bloqueo.



Recuerde, una excepción es solo un objeto, pero con una característica importante: debe extenderse desde el

|_+_|

clase o cualquier subclase de





|_+_|

. Si bien Java tiene todo tipo de excepciones integradas, también puede crear las suyas propias si lo desea. Algunos de los excepciones más comunes de Java incluir:

  • |_+_|
  • |_+_|
  • |_+_|
  • |_+_|
  • |_+_|

Entonces, ¿qué sucede cuando lanzas una excepción?





Primero, Java busca dentro del método inmediato para ver si hay código que maneje el tipo de excepción que arrojó. Si no existe un controlador, examina el método que llamó al método actual para ver si existe un controlador allí. Si no, mira el método que llamó ese método, y luego el siguiente método, etc. Si no se detecta la excepción, la aplicación imprime un seguimiento de la pila y luego se bloquea. (En realidad, tiene más matices que simplemente fallar, pero ese es un tema avanzado más allá del alcance de este artículo).

A seguimiento de pila es una lista de todos los métodos que Java atravesó mientras buscaba un manejador de excepciones. Así es como se ve un seguimiento de pila:

|_+_|

Podemos extraer mucho de esto. Primero, la excepción lanzada fue un

|_+_|

. Ocurrió en el

|_+_|

método en la línea 16 de Book.java. Ese método fue llamado desde

|_+_|

en la línea 25 de Author.java. Ese se llamó al método desde

|_+_|

en la línea 14 de Bootstrap.java. Como puede ver, saber todo esto facilita la depuración.

Pero nuevamente, el verdadero beneficio de las excepciones es que puede 'manejar' la condición anormal detectando la excepción, arreglando las cosas y reanudando la aplicación sin fallar.

Uso de excepciones de Java en el código

Digamos que tienes

|_+_|

que toma un número entero y ejecuta alguna lógica que podría romperse si el número entero es menor que 0 o mayor que 100. Este podría ser un buen lugar para lanzar una excepción:

cómo pasar los sitios web bloqueados en la escuela
|_+_|

Para detectar esta excepción, debe ir a donde

|_+_|

se llama y usa el bloque try-catch :

|_+_|

Todo dentro del tratar El bloque se ejecutará en orden hasta que se lance una excepción. Tan pronto como se lanza una excepción, se omiten todas las declaraciones posteriores y la lógica de la aplicación salta inmediatamente al captura cuadra.

En nuestro ejemplo, ingresamos al bloque try e inmediatamente llamamos

|_+_|

. Dado que 200 no está entre 0 y 100, un

|_+_|

es aventado. Esto termina inmediatamente la ejecución de

|_+_|

, omite el resto de la lógica en el bloque try (

|_+_|

nunca se llama) y reanuda la ejecución dentro del bloque catch.

¿Qué pasaría si llamamos

|_+_|

¿en lugar de? los

|_+_|

nunca sería arrojado.

|_+_|

se ejecutaría normalmente. El bloque try se ejecutaría normalmente, llamando

|_+_|

cuando se completa someMethod (). Cuando

|_+_|

termina, el bloque de captura se omitiría y

|_+_|

continuaría.

Tenga en cuenta que puede tener varios bloques de captura por bloque de prueba:

|_+_|

También tenga en cuenta que un opcional finalmente el bloque también existe:

|_+_|

El código dentro de un bloque finalmente es siempre ejecutado pase lo que pase. Si tiene una declaración de retorno en el bloque try, el bloque finalmente se ejecuta antes de salir del método. Si lanza otra excepción en el bloque de captura, el bloque finalmente se ejecuta antes de que se lance la excepción.

Debes usar el bloque finalmente cuando tengas objetos que necesiten limpiarse antes de que finalice el método. Por ejemplo, si abrió un archivo en el bloque try y luego lanzó una excepción, el bloque finalmente le permite cerrar el archivo antes de salir del método.

Tenga en cuenta que puede tener un bloque finalmente sin un bloque de captura:

|_+_|

Esto le permite hacer cualquier limpieza necesaria mientras permite que las excepciones lanzadas se propaguen por la pila de invocación del método (es decir, no desea manejar la excepción aquí, pero aún necesita limpiar primero).

Excepciones marcadas frente a no marcadas en Java

A diferencia de la mayoría de los lenguajes, Java distingue entre excepciones marcadas y excepciones no comprobadas (por ejemplo, C # solo tiene excepciones sin marcar). Una excepción comprobada debe quedar atrapado en el método donde se lanza la excepción o de lo contrario el código no se compilará.

Para crear una excepción marcada, extienda desde

|_+_|

. Para crear una excepción sin marcar, amplíe desde

|_+_|

.

Cualquier método que arroje una excepción marcada debe indicar esto en la firma del método usando el lanza palabra clave. Dado que Java está integrado

|_+_|

es una excepción marcada, el siguiente código no se compilará:

|_+_|

Primero debe declarar que lanza una excepción marcada:

|_+_|

Tenga en cuenta que se puede declarar que un método lanza una excepción, pero en realidad nunca lanza una excepción. Aun así, será necesario capturar la excepción o, de lo contrario, el código no se compilará.

¿Cuándo debería utilizar las excepciones marcadas o no?

La documentación oficial de Java tiene una página sobre esta pregunta . Resume la diferencia con una regla empírica sucinta: 'Si es razonable esperar que un cliente se recupere de una excepción, conviértala en una excepción marcada. Si un cliente no puede hacer nada para recuperarse de la excepción, conviértalo en una excepción sin marcar. '

Pero esta guía puede estar desactualizada. Por un lado, las excepciones marcadas dan como resultado un código más robusto. Por otro lado, ningún otro lenguaje ha verificado las excepciones de la misma manera que Java, lo que muestra dos cosas: una, la función no es lo suficientemente útil para que otros lenguajes la roben, y dos, puedes vivir absolutamente sin ellas. Además, las excepciones marcadas no funcionan bien con las expresiones lambda introducidas en Java 8.

Directrices para el uso de excepciones de Java

Las excepciones son útiles pero fáciles de usar y abusar. Aquí hay algunos consejos y mejores prácticas para ayudarlo a evitar ensuciarlos.

  • Prefiera excepciones específicas a excepciones generales. Utilice NullPointerException sobre Exception cuando sea posible, de lo contrario utilice Exception sobre NullPointerException cuando sea posible.
  • Nunca atrapar NumberFormatException ! El IllegalArgumentException clase en realidad se extiende RuntimeException , y el bloque catch realmente funciona con IllegalStateException o cualquier clase que amplíe Throwable. Sin embargo, el Exception in thread 'main' java.lang.NullPointerException
    at com.example.myproject.Book.getTitle(Book.java:16)
    at com.example.myproject.Author.getBookTitles(Author.java:25)
    at com.example.myproject.Bootstrap.main(Bootstrap.java:14)
    la clase también extiende NullPointerException , y nunca querrás atrapar un getTitle() porque getBookTitles() s indican problemas graves irrecuperables.
  • Nunca atrapar main() ! someMethod() extiende public void someMethod(int value) {
    if (value 100) {
    throw new
    IllegalArgumentException , por lo que cualquier bloque que capture someMethod() también capturará public void callingMethod() {  
    try {
    someMethod(200);
    someOtherMethod();
    } catch (IllegalArgumentException e) {
    // handle the exception in here
    }
    // ...
    }
    , y esa es una excepción muy importante con la que no querrá meterse (especialmente en aplicaciones de subprocesos múltiples) a menos que sepa lo que está haciendo. Si no sabe qué excepción atrapar en su lugar, considere no atrapar nada.
  • Utilice mensajes descriptivos para facilitar la depuración. Cuando lanza una excepción, puede proporcionar un someMethod() mensaje como argumento. Se puede acceder a este mensaje en el bloque catch usando IllegalArgumentException , pero si la excepción nunca se detecta, el mensaje también aparecerá como parte del seguimiento de la pila.
  • Trate de no detectar e ignorar las excepciones. Para evitar el inconveniente de las excepciones comprobadas, muchos programadores novatos y perezosos configurarán un bloque de captura pero lo dejarán vacío. ¡Malo! Manéjelo siempre con elegancia, pero si no puede, al menos imprima un seguimiento de la pila para que sepa que se lanzó la excepción. Puede hacer esto usando el someMethod() método.
  • Tenga cuidado con el uso excesivo de excepciones. Cuando tienes un martillo, todo parece un clavo. Cuando aprenda sobre las excepciones por primera vez, puede sentirse obligado a convertir todo en una excepción ... hasta el punto en que la mayor parte del flujo de control de su aplicación se reduce al manejo de excepciones. Recuerde, las excepciones están destinadas a sucesos 'excepcionales'.

Ahora debería estar lo suficientemente cómodo con las excepciones para comprender qué son, por qué se usan y cómo incorporarlas en su propio código. Si no comprende completamente el concepto, ¡está bien! Me tomó un tiempo hacer 'clic' en mi cabeza, así que no sienta que tiene que apresurarse. Tome su tiempo.

¿Tienes alguna pregunta? ¿Conoce algún otro consejo relacionado con excepciones que me haya perdido? ¡Compártelos en los comentarios a continuación!

Cuota Cuota Pío Correo electrónico Cómo crear un diagrama de flujo de datos para visualizar datos de cualquier proyecto

Los diagramas de flujo de datos (DFD) de cualquier proceso lo ayudan a comprender cómo fluyen los datos desde el origen al destino. ¡Aquí le mostramos cómo crearlo!

Leer siguiente
Temas relacionados
  • Programación
  • Java
Sobre el Autor Joel Lee(1524 Artículos publicados)

Joel Lee es el editor en jefe de MakeUseOf desde 2018. Tiene un B.S. en Ciencias de la Computación y más de nueve años de experiencia profesional en redacción y edición.

encontrar un símbolo dibujándolo
Más de Joel Lee

Suscríbete a nuestro boletín

¡Únase a nuestro boletín de noticias para obtener consejos técnicos, reseñas, libros electrónicos gratuitos y ofertas exclusivas!

Haga clic aquí para suscribirse