Introducción a los Asertos (Assertions)

Antes de nada, se conoce como aserto a una instrucción que contiene una expresión booleana de la que el programador sabe que en un momento dado de la ejecución del programa se debe evaluar a verdadero. Todos aquellos que hayan visto alguna vez la verificación formal de algoritmos saben de que estamos hablando. Ejemplos de asertos son las precondiciones, postcondiciones y los invariantes. Volviendo a la definición, observamos que verificando que esta expresion booleana, el aserto, es cierta, el sistema comprueba que el programa se ejecuta dentro de los límites que el programador le marca y ademas reduce la posibilidad de errores.

Los asertos no son nada nuevo en programación, de hecho los asertos ya estaban previstos en la especificación inicial de oak (el lenguaje precursor de Java) pero fueron desestimados por que no había tiempo suficiente para hacer una implementación satisfactoria.

Uso

Para declarar un aserto en una clase Java, se usa la palabra clave assert que tiene la siguiente sintáxis:

assert Expresion1;
assert Expresión1:Expresión2;

En cualquiera de los dos casos Expresión1 tiene que ser una expresión booleana o se producirá un error de compilación. Cuando se evalúa un aserto que solo tenga Expresión1, se comprueba la veracidad de la expresión y si es verdadera se continúa la ejecución del programa, pero si es falsa, se lanza una excepción de tipo AssertionError. Si el aserto contiene además una Expresión2 y Expresión1 es falsa, se evalúa Expresion2 y se le pasa como parámetro al constructor del AssertionError (Si Expresion1 se evalúa como cierto, la segunda expresión no se evalúa).

Compilación

Para que el compilador del JDK (javac) entienda la nueva instrucción, se le debe pasar como parámetro -source 1.4, por ejemplo:

javac -source 1.4 Aserto.java

Esto le indica al compilador que el código que recibe utiliza características del lenguaje aparecidas en la versión 1.4 del JDK.

Ahora bien, ¿Que ocurre con las classes ya escritas que usan assert como variable?. Pues que no compilarán, aunque si ya estan compiladas seguirán ejecutándose sin problemas en la nueva versión del JDK.

Activación/Desactivación

Los asertos estan pensados para la comprobación de invariantes (condiciones que se cumplen siempre en un determinado trozo de código), por lo que tienen mas interés en la etapa de desarrollo. Por esto se puede desactivar y activar la comprobación de los asertos. Por defecto la comprobación de los asertos esta desactivada y se proporcionan dos opciones para el intérprete del JDK (java).

java -enableassertions (-ea), para activar la comprobación.
java -disableassertions (-da), para desactivar la comprobación.

Si estos modificadores se escriben tal cual, se activará o desactivará la comprobación de asertos para la clase que se pretende ejecutar. Pero si lo que se quiere es activar/desactivar la comprobación de los asertos en un determinado paquete o de una determinada clase:

java -enableassertions:Saludos.Hola... HolaMundo

(Activa asertos en el paquete Saludos.Hola, por los puntos ...)

java -enableassertions:Saludos.Hola HolaMundo

(Activa asertos la clase Saludos.Hola, por que no lleva puntos)
Y lo mismo para disable:

java -disablessertions:Saludos.Hola... HolaMundo
java -disableassertions:Saludos.Hola HolaMundo

Tambien se puede activar para unos y desactivar para otros:

java -ea:Camion.Rueda... -da:Camion.Freno Camion.Conducir

En resumen la sintáxis es la siguiente:

java [-enableassertions | -ea] [:<package name>"..." | :<class name>]
java [-disableassertions | -da] [:<package name>"..." | :<class name>]

Ejemplos de uso

Bien, vale ya de teoría y pasemos a la práctica. Los asertos prometen mucho, hasta ahora cualquiera que programase en Java y supiese que alguna condición debía ser cierta en alguna parte del código (el invariante) lo colocaba como comentario:

			if (a==1){
			...
			} else if (a==2){
			...
			} else { //cuando a==3
			...
			}

Aqui es donde se puede aplicar la nueva instrucción assert, (y en general para cualquier invariante):

			if (a==1){
			...
			} else if (a==2){
			...
			} else {
			assert (a==3)
			...
			}

De esta manera conseguimos proteger el else. Si se entra por el else y el aserto no se cumple, se genera una excepción de tipo AssertionError.

Otro candidato para los asertos es una sentencia switch que no tenga cláusula default. En este caso el aserto comprobará que nunca se entra por el default, de esta manera:

		switch (suerte){
		 case Moneda.CARA:
		 ...
		 return;
		 case Moneda.CRUZ:
		 ...
		 return;
		 case default:
		 assert false;
		}

Se habrá dado cuenta de la potencia de utilizar assert false en cualquier lugar del programa donde se supone no se debe entrar nunca.

Puede que su programa deba hacer una comprobación férrea de determinados valores de variables, lo que consigue incluyendo asertos que las comprueben alli donde es necesario, pero seguramente tambien querrá comprobar que la comprobación de asertos está activada, pues bien, esta es una manera de que al cargar una clase se asegure que se ejecuta solo si la comprobación de asertos esta activada; coloque este código como primer código a ejecutar de su clase (el sitio ideal es el constructor):

		static {
 		 boolean assertsActivado = false;
        	 assert assertsActivado = true; 
        	 if (!assertsActivado)
            	 throw new RuntimeException("¡Debe activar la comprobacion de asertos!");
    		}

El código es estático, por lo que siempre se ejecutará. Si la comprobación de asertos esta desactivada no se hará caso del aserto y se generará la excepción RuntimeException, en cambio si esta activada, se cambiará el valor de assertsActivado y no se generará la excepción. Debe darse cuenta de que el compilador de java no prohibe este tipo de asertos con efectos laterales, por lo que debe tener cuidado.

Conclusión

Los asertos son un buen método para comprobar valores de variables, expresiones y para comprobar estados del programa por donde no se tiene que pasar. Bien es cierto que esto también se puede hacer con una serie de If's, pero no sería tan eficiente, y sobre todo no se podría desactivar cuando uno quiera. Como moraleja final, consulten este link al informe de fallo del Ariane 5 (explotó en el aire por una mala conversion de un float de 64 bits a un integer de 32) donde los asertos (comprobando la buena conversión) hubiesen evitado la catástrofe.

Enlaces

Especificación de asertos de Sun: http://java.sun.com/j2se/1.4/docs/guide/lang/assert.html

COMPARTE ESTE ARTÍCULO

ENVIAR A UN AMIGO
COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN GOOGLE +
ARTÍCULO ANTERIOR

SIGUIENTE ARTÍCULO

¡SÉ EL PRIMERO EN COMENTAR!
Conéctate o Regístrate para dejar tu comentario.