2009-08-14 14 views
46

¿Cuál es la diferencia entre el manejo de excepciones Java y el uso de las condiciones assert?Excepción Vs Aserción

Se sabe que Assert es de dos tipos. Pero, ¿cuándo deberíamos usar la palabra clave assert?

+0

No puedo creer lo que pienso: esta pregunta fue editada por un usuario de 166k y todavía se ve así. –

+1

Sí, bastante mal. Lo limpié un poco más. No estoy seguro de qué significa JavaResp por "dos tipos", así que lo dejé allí. Mi mejor estimación es precondición vs postcondición según http://www.deitel.com/articles/java_tutorials/20060106/Assertions.html –

+0

"Algunos más", que significa "renovación completa" en este caso. – JakeSteam

Respuesta

72

Utilice las aserciones para las verificaciones lógicas internas dentro de su código, y las excepciones normales para las condiciones de error fuera del control de su código inmediato.

No olvide que las afirmaciones pueden activarse y desactivarse: si le importan cosas como la validación de argumentos, esto debería ser explícito utilizando excepciones. (Se podría, sin embargo, opta por realizar la validación de argumentos en métodos privados usando afirmaciones, sobre la base de que una violación en ese punto se debe a un fallo interno en lugar de un error externo.)

Alternativamente Es toda razonable (IMO) para usar excepciones para todo. Personalmente, no uso afirmaciones en absoluto, pero es una cuestión de preferencia personal hasta cierto punto. (Ciertamente puede haber argumentos objetivos a favor y en contra de aserciones, pero no es lo suficientemente claro para eliminar las preferencias por completo.)

+4

Vale la pena señalar que algunos lenguajes implementan aserciones utilizando excepciones. En dichos idiomas, su afirmación de que "es razonable usar excepciones para todo" es tan cierta que es redundante. :) – Imagist

+0

Según lo especificado por [dasblinkenlight] (http://programmers.stackexchange.com/a/137167/175034): "Las excepciones no verificadas están diseñadas para detectar errores de programación de los usuarios de su biblioteca, mientras que las aserciones están diseñadas para detectar errores en tu propia lógica. Estas son cuestiones separadas que no deberían mezclarse ". – MaxZoom

1

El asentar es para fines de depuración y su condición desencadenante no debería ocurrir (puntero nulo cuando no debería haber , etc.)

excepción es para los eventos especiales del sistema que siempre pueden suceder: FileNotFound, ConnectionToServerLost, etc.

6

excepción es un mecanismo de comprobar si la aplicación se está ejecutando sin errores esperados o inesperados o no. Entonces, vemos que las excepciones se usan básicamente para manejar incluso las condiciones imprevistas durante la ejecución de una aplicación de una mejor manera y, por lo tanto, el uso de excepciones resulta eficazmente en una aplicación sólida.

Las aserciones nunca deben ser parte de la implementación de algunas funcionalidades de la aplicación. Solo deberían usarse para verificar las suposiciones, solo para estar seguros de que lo que asumimos al diseñar la solución también es válido en la práctica.

referencia: http://geekexplains.blogspot.com/2008/06/asserions-in-java-assertions-vs.html

24

aserciones Java se construyen en la parte superior de las excepciones de Java y el manejo de excepciones. De hecho, cuando una afirmación de Java falla, el resultado es una excepción AssertionError que se puede capturar como cualquier otra excepción de Java. Las principales diferencias entre las excepciones y las afirmaciones son:

  • Las afirmaciones son destinados a servir únicamente como un medio para detectar errores de programación, también conocido como errores. Por el contrario, una excepción puede indicar otros tipos de error o condición "excepcional"; p.ej. entrada de usuario no válida, archivos perdidos, montón completo, etc.
  • El lenguaje Java proporciona soporte sintáctico para aserciones, en forma de la declaración assert. Compare los siguientes:

    if (x != y) { 
        throw new SomeException("x != y"); 
    } 
    
    assert x != y; 
    
  • que es más importante, Java le permite activar o desactivar la afirmación de la comprobación a nivel mundial o en clases individuales cuando se inicia la JVM.

Nota: algunas personas dicen que usted debe siempre el código de producción plazo con la afirmación comprobación desactivado.Tiendo a estar en desacuerdo con esto como una declaración general. Si se sabe que su código de producción es estable Y necesita exprimir el último rendimiento, entonces desactivar las afirmaciones es bueno. Pero, si un (digamos) rendimiento del 10% no es un problema real, preferiría que una aplicación muera con un error de aserción si la alternativa es continuar y dañar mi base de datos.

@Mario Ortegón comentó así:

El "apagar" es porque afirmaciones pueden ser utilizados para verificar el resultado de un algoritmo optimizado mediante la comparación de su aplicación contra un conocido, pero lento, algoritmo. Entonces, en desarrollo, está bien invocar ese método O(N^3) para afirmar que el algoritmo O(log N) funciona según lo previsto. Pero esto es algo que no quieres en producción.

Independientemente de si usted piensa que es una buena práctica para apagar las afirmaciones de la producción, es definitivamente una mala práctica escribir afirmaciones que tienen un impacto significativo en el rendimiento cuando está activado. ¿Por qué? Porque significa que ya no tiene la opción de habilitar las aserciones en producción (para rastrear un problema) o en su prueba de estrés/capacidad. En mi opinión, si necesita hacer O(N^3) pruebas previas o posteriores a la condición, debe hacerlo en las pruebas de su unidad.

+0

El "apagado" se debe a que las afirmaciones se pueden usar para verificar el resultado de un algoritmo optimizado comparando su implementación con un algoritmo bien conocido pero lento. Entonces, en desarrollo, está bien invocar ese método O (n3) para afirmar que el algoritmo O (log N) funciona como se desea ... Pero es algo que * no * quieres en producción. –

4

Ejemplo de un buen uso de Assert:

assert flibbles.count() < 1000000; // too many flibbles indicate something is awry 
log.warning("flibble count reached " + flibbles.count()); // log in production as early warning 

yo personalmente creo que afirman debe única ser utilizada cuando se sabe que algo está fuera deseables límites, pero puede estar seguro de que es razonablemente seguro continuar. En todas las demás circunstancias (no dude en señalar las circunstancias en las que no he pensado) use excepciones para fallar de manera rápida y difícil.

El principal inconveniente para mí es si desea derribar un sistema en vivo/producción con una excepción para evitar corrupción y facilitar la resolución de problemas, o si ha encontrado una situación que nunca debe continuar desapercibida en prueba/depurar versiones, pero se podría permitir que continúen en producción (registrando una advertencia, por supuesto).

cf. http://c2.com/cgi/wiki?FailFast véase también mi C# copia de esta respuesta: Debug.Assert vs. Specific Thrown Exceptions

+3

Las afirmaciones son mucho, * mucho * afirmaciones más fuertes que eso. Están destinados a documentar (y al ejecutar en depuración, verificar) sus suposiciones y/o garantías sobre lo que * siempre * será verdadero en un punto particular del código. ** Las fallas de aserción nunca deben suceder **, si lo hacen, significa que (a) sus suposiciones fueron incorrectas, y (b) no se puede confiar en que cualquier código a partir de ese momento haga lo correcto (porque en algún lugar a lo largo de la línea, ya está * hecho * lo incorrecto, y ahora está operando "fuera de límites"). – cHao

+0

Si sabe que algo nunca debería suceder, ¿por qué lo dejaría pasar sin marcar en el código de producción donde las afirmaciones están desactivadas? Seguramente usarías una excepción para asegurarte de que la suposición rota está atrapada. Sé que voy en contra de la sabiduría recibida aquí, pero estoy interesado en ver qué argumentos convincentes puedo desentrañar al ser contrario. ¡Gracias por tu comentario! –

+1

Las excepciones son para cosas que normalmente no sucede, pero podría ser. Faltan archivos, interrupciones de la red, tal vez datos no válidos. Cosas que tu código no puede controlar. Las afirmaciones son para cosas que, si su código funciona correctamente, * nunca * sucede. Están destinados a una doble verificación durante la depuración. En producción, su código ya debería ser lo suficientemente seguro del resultado que ya no tiene que comprobar más. – cHao

0

aserción se utiliza para la depuración de los supuestos que se requieren para ser controladas en tiempo de ejecución solamente activando la función de aserción mientras excepción es para comprobar las condiciones específicas que deben comprobarse durante la ejecución de la programa para evitar que el programa termine.

4

Las aserciones son muy similares a las excepciones, de hecho, al igual que las excepciones, marcarán un problema, pero a diferencia de las excepciones, no sugerirán ninguna ruta de ejecución alternativa, sino que simplemente fallarán. ¿Por qué usar aserciones, si puede hacer lo mismo, y más con excepciones?

Úselos cuando los problemas no se reparen, y en realidad NUNCA DEBERÍAN SUCEDER EN PRIMER LUGAR. Esto suena raro al principio: ¿no queremos proteger nuestro código de TODOS los posibles problemas? Por lo general, sí. Pero hay un caso en que no lo hacemos. Este caso se llama: "Diseño por contrato".

Supongamos que está escribiendo una solicitud para un banco. Como desarrollador, no es posible que soporte todas las condiciones financieras posibles. Entonces, antes de comenzar a codificar, obtiene una especificación del banco que le proporciona los rangos válidos que esta aplicación debe admitir. Entonces, su aplicación está diseñada por contrato (según las especificaciones del banco).Este contrato definirá los principios fundamentales que siempre deberían ser ciertos para que su aplicación funcione. Estos principios fundamentales se llaman "invariantes" (porque no pueden cambiar). El diseño por contrato simplifica su vida como desarrollador: usted solo es responsable de respaldar el alcance del trabajo definido en el contrato.
Es importante verificar los valores de estas invariantes en su código, pero no debe verificarlos como si fueran excepciones y tratar de evitarlos. Si están equivocados, debe fallar porque las entradas no han cumplido sus obligaciones contractuales.

Lo interesante es que si no pone una afirmación en el lugar crítico y las invariantes dejan de ser válidas, su código fallará de todos modos. Simplemente no sabrás por qué. Entonces, para resumir, las afirmaciones se usan para verificar las invariantes. Van de la mano del principio "diseño por contrato". Úselos para solucionar un problema, por eso se desactivan en producción.

Otro caso de uso: si confía en una biblioteca externa en la que no confía plenamente, es posible que desee usar declaraciones de afirmación al llamarla.

Algunos también usan aserciones como un sustituto rápido y sucio de una excepción (ya que es muy fácil de hacer), pero conceptualmente eso no es lo correcto.

Cuestiones relacionadas