java - ejemplo - Cuándo usar una aserción y cuándo usar una excepción
private jlabel (11)
Bueno, de vuelta en Microsoft, la recomendación fue lanzar Excepciones en todas las API que publicas públicamente y usar Asserts en todo tipo de suposiciones que hagas sobre el código que es interno. Es una definición algo suelta, pero supongo que depende de cada desarrollador trazar la línea.
En cuanto al uso de Excepciones, como su nombre lo indica, su uso debe ser excepcional, por lo que para el código que presenta arriba, la llamada a getGroup
debe devolver null
si no existe servicio. La excepción solo debería ocurrir si un enlace de red se cae o algo así.
Supongo que la conclusión es que le queda un poco al equipo de desarrollo para que cada aplicación defina los límites de las excepciones assert vs.
La mayoría de las veces usaré una excepción para verificar una condición en mi código. Me pregunto cuándo es el momento apropiado para usar una afirmación.
Por ejemplo,
Group group=null;
try{
group = service().getGroup("abc");
}catch(Exception e){
//I dont log error because I know whenever error occur mean group not found
}
if(group !=null)
{
//do something
}
¿Podría indicar cómo encaja una afirmación aquí? ¿Debería usar una afirmación?
Parece que nunca uso aserciones en el código de producción y solo veo aserciones en pruebas unitarias. Sé que en la mayoría de los casos, puedo usar la excepción para hacer la comprobación como se indicó anteriormente, pero quiero saber la forma adecuada de hacerlo "profesionalmente".
Como regla general:
- Use las aserciones para verificaciones de consistencia interna donde no importa en absoluto si alguien las desactiva. (Tenga en cuenta que el comando
java
desactiva todas las aserciones de manera predeterminada). - Utilice pruebas regulares para cualquier tipo de control de lo que no se debe apagar. Esto incluye controles preventivos que protegen contra el daño potencial causado por errores y cualquier información / solicitud / validación proporcionada por los usuarios o servicios externos.
El siguiente código de su pregunta es de mal estilo y posiblemente con errores
try {
group = service().getGroup("abc");
} catch (Exception e) {
//i dont log error because i know whenever error occur mean group not found
}
El problema es que NO SABES que una excepción significa que el grupo no se encontró. También es posible que la llamada a service()
lanzado una excepción, o que haya devuelto un null
que provocó una NullPointerException
.
Cuando detecta una excepción "esperada", debe detectar solo la excepción que está esperando. Al capturar java.lang.Exception
(y especialmente al no iniciar sesión), hace que sea más difícil diagnosticar / depurar el problema y, potencialmente, permitir que la aplicación haga más daño.
Confieso que estoy un poco confundido por tu pregunta. Cuando no se cumple una condición de aserción, se lanza una excepción. Confusamente, esto se llama AssertionError . Tenga en cuenta que no está marcado, como (por ejemplo) IllegalArgumentException que se lanza en circunstancias muy similares.
Entonces usando aserciones en Java
- es un medio más conciso de escribir una condición / bloque de tiro
- le permite activar / desactivar estos controles a través de los parámetros de JVM. Normalmente dejaría estos controles todo el tiempo, a menos que afecten el rendimiento del tiempo de ejecución o tengan una penalización similar.
Consulte la sección 6.1.2 (Afirmaciones contra otro código de error) de la documentación de Sun en el siguiente enlace.
http://www.oracle.com/technetwork/articles/javase/javapch06.pdf
Este documento ofrece el mejor consejo que he visto sobre cuándo usar las afirmaciones. Citando del documento:
"Una buena regla empírica es que debe usar una afirmación para casos excepcionales de los que le gustaría olvidarse. Una afirmación es la forma más rápida de tratar y olvidar una condición o estado que no espera tener que tratar con."
De acuerdo con este documento http://docs.oracle.com/javase/6/docs/technotes/guides/language/assert.html#design-faq-general , "La afirmación assert es apropiada para precondiciones no públicas, posteriores a la clase e invariantes de clase La comprobación previa de la condición pública aún debe realizarse mediante comprobaciones dentro de los métodos que dan como resultado excepciones particulares documentadas, como IllegalArgumentException y IllegalStateException. "
Si desea obtener más información sobre condiciones previas, condiciones posteriores e invariante de clases, consulte este documento: http://docs.oracle.com/javase/6/docs/technotes/guides/language/assert.html#usage-conditions . También contiene ejemplos de uso de aserciones.
Desafortunadamente las afirmaciones pueden ser deshabilitadas. Cuando está en producción, necesita toda la ayuda que puede obtener cuando rastrea algo imprevisto, por lo que se descalifica a sí mismo.
Fuera de mi mente (la lista puede estar incompleta y es demasiado larga para caber en un comentario), diría:
- use excepciones cuando verifique los parámetros pasados a métodos y constructores públicos o protegidos
- use excepciones cuando interactúa con el usuario o cuando espera que el código del cliente se recupere de una situación excepcional
- use excepciones para abordar los problemas que puedan ocurrir
- usar aserciones al verificar precondiciones, condiciones posteriores e invariantes de código privado / interno
- use aserciones para proporcionar retroalimentación a usted o a su equipo de desarrolladores
- use aserciones cuando verifique cosas que es muy poco probable que sucedan, de lo contrario significa que hay una falla grave en su aplicación
- use aserciones para declarar cosas que usted (supuestamente) sabe que son verdaderas
En otras palabras, las excepciones abordan la solidez de su aplicación mientras que las afirmaciones abordan su corrección.
Las afirmaciones están diseñadas para ser baratas de escribir, puedes usarlas en casi todas partes y estoy usando esta regla práctica: cuanto más estúpida sea la afirmación, más valiosa será y más información incorporará. Al depurar un programa que no se comporta de la manera correcta, seguramente comprobará las posibilidades de falla más obvias en función de su experiencia. Luego verificará si hay problemas que simplemente no pueden suceder: esto es exactamente cuando las afirmaciones ayudan mucho y ahorran tiempo.
La prueba de null solo capturará valores nulos que causan problemas, mientras que un try / catch como lo tiene captará cualquier error.
En general, try / catch es más seguro, pero un poco más lento, y debe tener cuidado de detectar todos los tipos de errores que puedan ocurrir. Así que yo diría usar try / catch - un día el código getGroup puede cambiar, y es posible que necesite esa red más grande.
Las afirmaciones deben usarse para verificar algo que nunca debería suceder, mientras que una excepción debe usarse para verificar algo que podría suceder.
Por ejemplo, una función puede dividirse por 0, por lo que se debe usar una excepción, pero se puede usar una afirmación para verificar que el disco rígido desaparece de repente.
Una afirmación detendría la ejecución del programa, pero una excepción permitiría que el programa continúe ejecutándose.
Tenga en cuenta que if(group != null)
no es una aserción, eso es solo un condicional.
Puede tener en cuenta esta diferencia simple mientras usa. Se usarán excepciones para verificar errores esperados e inesperados llamados errores comprobados y no comprobados, mientras que la aserción se usa principalmente para fines de depuración en el tiempo de ejecución para ver si las suposiciones son validadas o no.
Recuerde que las aserciones se pueden deshabilitar en el tiempo de ejecución mediante parámetros y están deshabilitadas de manera predeterminada , por lo tanto, no cuente con ellas, excepto para fines de depuración.
También debería leer el artículo de Oracle sobre assert para ver más casos donde usar - o no usar - assert.