java - tutorial - Lanza o prueba+atrapa
text box java (9)
¿Cuál es la regla general a la hora de decidir si agregar una cláusula throws a un método o usar un try-catch?
Según lo que he leído, los lanzamientos deben usarse cuando la persona que llama ha roto el final del contrato (objeto pasado) y el try-catch se debe usar cuando se produce una excepción durante una operación que se está llevando a cabo dentro del método. ¿Es esto correcto? Si es así, ¿qué debería hacerse por el lado de las personas que llaman?
PD: Búsqueda a través de Google y SO, pero me gustaría una respuesta clara sobre este.
Así es como lo uso:
Lanza:
- Solo quiere que el código se detenga cuando ocurre un error.
- Es bueno con métodos que son propensos a errores si no se cumplen ciertos requisitos previos.
Trata de atraparlo:
- Cuando desee que el programa se comporte de manera diferente con diferentes errores.
- Ideal si desea proporcionar errores significativos a los usuarios finales.
Conozco a mucha gente que siempre usa Throws porque es más limpio, pero no hay tanto control.
La decisión de agregar una cláusula try-catch o throws a sus métodos depende de "cómo desea (o tiene) que manejar su excepción".
Cómo manejar una excepción es una pregunta amplia y no trivial a responder. Involucra especialmente la decisión de dónde manejar la excepción y qué acciones implementar dentro del bloque catch. De hecho, cómo manejar una excepción debe ser una decisión de diseño global.
Para responder a sus preguntas, no hay una regla general.
Debe decidir dónde desea manejar su excepción y esa decisión suele ser muy específica para su dominio y los requisitos de la aplicación.
Mi regla personal para eso es simple:
- ¿Puedo manejarlo de una manera significativa (agregada de un comentario)? Así que pon el código en
try/catch
. Al manejarlo, me refiero a poder informar al usuario / recuperar del error o, en un sentido más amplio, ser capaz de entender cómo esta excepción afecta la ejecución de mi código. - En otro lugar, tíralo
Nota: esta respuesta ahora es una wiki de la comunidad, no dude en agregar más información.
Si el método donde surgió la excepción tiene una cantidad suficiente de información para manejarlo, entonces debería captar, generar información útil sobre lo que sucedió y qué datos se estaban procesando.
Si usa una captura de prueba, cuando se produce la excepción, los códigos restantes se seguirán ejecutando.
Si indica el método para lanzar la excepción, cuando ocurra la excepción, el código dejará de ejecutarse de inmediato.
Un método solo debe throws
una excepción si puede ofrecer garantías razonables sobre el estado del objeto, los parámetros que se pasan al método y cualquier otro objeto sobre el que actúe el método. Por ejemplo, un método que se supone que recupera de un conjunto un elemento que el llamante espera contener en el mismo puede throws
una excepción marcada si el elemento que se esperaba que existiera en la colección no lo hace. Una persona que llama que detecta esa excepción debe esperar que la colección no contenga el artículo en cuestión.
Tenga en cuenta que, si bien Java permitirá que las excepciones comprobadas se disparen a través de un método que se declara como lanzar excepciones de los tipos apropiados, dicho uso generalmente se debe considerar un antipatrón. Imagine, por ejemplo, que algún método LookAtSky()
se declara como una llamada FullMoonException
, y se espera que lo lance cuando la Luna está llena; imaginemos aún más, que LookAtSky()
llama a ExamineJupiter()
, que también se declara como throws FullMoonException
. Si ExamineJupiter()
arrojaba una FullMoonException
y si LookAtSky()
no la LookAtSky()
y no la LookAtSky()
ni la LookAtSky()
en algún otro tipo de excepción, el código que llamaba LookAtSky
supondría que la excepción era el resultado de que la luna de la Tierra estaba llena ; no tendría ni idea de que una de las lunas de Júpiter podría ser la culpable.
Las excepciones que una persona que llama puede esperar manejar (incluyendo esencialmente todas las excepciones marcadas) solo deben permitirse filtrar a través de un método si la excepción significará lo mismo para la persona que llama al método que para el método llamado. Si el código llama a un método que se declara como arrojando alguna excepción marcada, pero la persona que llama no espera que arroje esa excepción en la práctica (por ejemplo, porque cree que es un argumento de método previamente validado), la excepción marcada debe ser capturada y ajustada en algún tipo de excepción sin marcar. Si la persona que llama no espera lanzar la excepción, la persona que llama no puede esperar que tenga un significado particular.
try-catch pair se usa cuando desea proporcionar un comportamiento personalizado, en caso de que ocurra una excepción ..... en otras palabras ... tiene una solución de su problema (ocurrencia de excepción) según los requisitos de su programa .... .
Pero throws se usa cuando no tiene una solución específica con respecto al caso de ocurrencia de excepción ... simplemente no desea obtener una finalización anormal de su programa ....
Espero que sea correcto :-)
En general, un método debe lanzar una excepción a su llamador cuando no puede manejar el problema asociado localmente. Por ejemplo, si se supone que el método debe leerse desde un archivo con la ruta especificada, IOExceptions no se puede gestionar localmente de manera sensata. Lo mismo se aplica a las entradas no válidas, agregando que mi elección personal sería lanzar una excepción sin marcar como IllegalArgumentException en este caso.
Y debería capturar una excepción de un método llamado si
- es algo que puede manejarse localmente (por ejemplo, tratando de convertir una cadena de entrada a un número, y si la conversión falla, es completamente válido devolver un valor predeterminado en su lugar),
- o no debe lanzarse (por ejemplo, si la excepción proviene de una capa inferior específica de la implementación, cuyos detalles de implementación no deberían ser visibles para la persona que llama - por ejemplo, no quiero mostrar que mi DAO usa Hibernate para persistir mis entidades , entonces capturo todas las HibernateExceptions localmente y las convierto en mis propios tipos de excepciones).
- atrapa una excepción solo si puedes manejarla de una manera significativa
- declarar lanzar la excepción hacia arriba si debe ser manejada por el consumidor del método actual
- lanzar excepciones si son causadas por los parámetros de entrada (pero estos son más a menudo sin marcar)