Los desarrolladores hacen suposiciones sobre cómo se comportará nuestro código cuando se ejecute, pero no siempre tenemos razón. Sin certeza, resulta complicado escribir programas que funcionen correctamente en tiempo de ejecución. Las aserciones de Java proporcionan una manera relativamente fácil de verificar que su lógica de programación sea correcta. Lo que aprenderá en este tutorial de Java En este artículo, aprenderá qué son las aserciones, cómo escribirlas y cómo usarlas en sus programas Java: ¿Qué son las afirmaciones de Java? Cómo escribir una aserción en Java Afirmaciones con condiciones previas y poscondiciones La diferencia entre aserciones de Java y excepciones de Java descargar Descargue el código fuente para ver ejemplos en este tutorial. Creado por Jeff Friesen. ¿Qué son las afirmaciones de Java? Antes de JDK 1.4, los desarrolladores solían utilizar comentarios para documentar suposiciones sobre la corrección del programa. Pero los comentarios en realidad no nos ayudan a probar y depurar nuestras suposiciones. El compilador ignora los comentarios, por lo que no hay forma de utilizarlos para detectar errores. Los desarrolladores tampoco suelen actualizar los comentarios cuando cambian el código. En JDK 1.4, las afirmaciones se introdujeron como un nuevo mecanismo para probar y depurar suposiciones sobre el código Java. En esencia, las aserciones son entidades compilables que se ejecutan en tiempo de ejecución, suponiendo que las haya habilitado para las pruebas del programa. Puede programar aserciones para que le notifiquen los errores donde ocurren, lo que reduce en gran medida la cantidad de tiempo que de otro modo dedicaría a depurar un programa defectuoso. Las aserciones se utilizan para codificar los requisitos que hacen que un programa sea correcto o no mediante condiciones de prueba (expresiones booleanas). para valores verdaderos y notificar al desarrollador cuando dichas condiciones sean falsas. El uso de aserciones puede aumentar en gran medida su confianza en la exactitud de su código. Cómo escribir una aserción en Java Las aserciones se implementan mediante la declaración de afirmación y la clase java.lang.AssertionError. Esta declaración comienza con la palabra clave afirmar y continúa con una expresión booleana. Se expresa sintácticamente de la siguiente manera: afirmar BooleanExpr; Si BooleanExpr se evalúa como verdadero, no sucede nada y la ejecución continúa. Sin embargo, si la expresión se evalúa como falsa, se crea una instancia de AssertionError y se lanza, como se demuestra en el Listado 1. Listado 1. Ejemplo 1 de aserciones de Java public class AssertDemo { public static void main(String[] argumentos) { int x = -1; afirmar x >= 0; } }La afirmación en el Listado 1 indica la creencia del desarrollador de que la variable x contiene un valor mayor o igual a 0. Sin embargo, este claramente no es el caso; La ejecución de la declaración de afirmación da como resultado un AssertionError. Compile el Listado 1 (javac AssertDemo.java) y ejecútelo con las aserciones habilitadas (java -ea AssertDemo). Debería observar el siguiente resultado: Excepción en el hilo «main» java.lang.AssertionError en AssertDemo.main(AssertDemo.java:6) Este mensaje es algo críptico porque no identifica qué causó que se lanzara AssertionError. Si desea un mensaje más informativo, utilice la siguiente declaración de afirmación: afirmar ExprBooleana: expr; Aquí, expr es cualquier expresión (incluida la invocación de un método) que puede devolver un valor; no se puede invocar un método con un tipo de retorno nulo. Una expresión útil es una cadena literal que describe el motivo del error, como se demuestra en el Listado 2. Listado 2. Ejemplo 2 de aserciones de Java public class AssertDemo { public static void main(String[] argumentos) { int x = -1; afirmar x >= 0: «x < 0"; } }Compile el Listado 2 (javac AssertDemo.java) y ejecútelo con las aserciones habilitadas (java -ea AssertDemo). Esta vez, debería observar el siguiente resultado ligeramente ampliado, que incluye el motivo del AssertionError arrojado: Excepción en el subproceso "main" java.lang.AssertionError: x < 0 en AssertDemo.main(AssertDemo.java:6) Para cualquier ejemplo , ejecutar AssertDemo sin la opción -ea (habilitar afirmaciones) no genera resultados. Cuando las aserciones no están habilitadas, no se ejecutan, aunque todavía están presentes en el archivo de clase. Aserciones con condiciones previas y poscondiciones Las aserciones prueban las suposiciones de un programa verificando que sus diversas condiciones previas y poscondiciones no se violen, alertando al desarrollador cuando se produce una infracción. : Una condición previa es una condición que debe evaluarse como verdadera antes de la ejecución de alguna secuencia de código. Las condiciones previas garantizan que las personas que llaman mantengan sus contratos con los destinatarios. Una poscondición es una condición que debe evaluarse como verdadera después de la ejecución de alguna secuencia de código. Las poscondiciones garantizan que los destinatarios de la llamada mantengan sus contratos con las personas que llaman. Escribir condiciones previas Puede hacer cumplir condiciones previas en métodos y constructores públicos realizando comprobaciones explícitas y lanzando excepciones cuando sea necesario. Para los métodos auxiliares privados, puede imponer condiciones previas especificando aserciones. Considere el ejemplo del Listado 3. Listado 3. Ejemplo 3 de aserciones de Java import java.io.FileInputStream; importar java.io.InputStream; importar java.io.IOException; class PNG { /** * Cree una instancia PNG, lea el archivo PNG especificado y * decodificalo en estructuras adecuadas. * * @param filespec ruta y nombre del archivo PNG a leer * * @throws NullPointerException cuando filespec es * null
*/ PNG(String filespec) throws IOException { // Aplicar condiciones previas en constructores y // métodos no privados. if (filespec == null) lanza una nueva NullPointerException («filespec es nulo»); intentar (FileInputStream fis = nuevo FileInputStream(filespec)) { readHeader(fis); } } private void readHeader(InputStream is) throws IOException { // Confirma que se cumple la condición previa en los // métodos auxiliares privados. afirmar es! = nulo: «nulo pasado a es»; } } clase pública AssertDemo { principal vacía estática pública (Cadena[] args) lanza IOException { PNG png = nuevo PNG((args.length == 0) ? null : args[0]); } }La clase PNG del Listado 3 es el comienzo mínimo de una biblioteca para leer y decodificar archivos de imagen PNG. El constructor compara explícitamente la especificación de archivo con nulo y genera NullPointerException cuando este parámetro contiene nulo. El punto es hacer cumplir la condición previa de que filespec no contenga nulo. No es apropiado especificar afirmar especificación de archivo! = nulo; porque la condición previa mencionada en el Javadoc del constructor no se cumpliría (técnicamente) cuando se deshabilitaran las afirmaciones. (De hecho, sería un honor porque FileInputStream() arrojaría NullPointerException, pero no debería depender de un comportamiento no documentado). Sin embargo, afirmar es apropiado en el contexto del método auxiliar privado readHeader(), que eventualmente se completará para leer y decodificar el encabezado de 8 bytes de un archivo PNG. La condición previa a la que siempre se le pasa un valor no nulo siempre se cumplirá. Escritura de condiciones posteriores Las condiciones posteriores generalmente se especifican mediante aserciones, independientemente de si el método (o constructor) es público o no. Considere el ejemplo del Listado 4. Listado 4. Ejemplo 4 de aserciones de Java public class AssertDemo { public static void main(String[] argumentos) {int[] matriz = {20, 91, -6, 16, 0, 7, 51, 42, 3, 1}; ordenar (matriz); para (elemento int: matriz) System.out.printf(«%d «, elemento); Sistema.out.println(); } booleano estático privado está ordenado (int[] x) { para (int i = 0; i < x.length - 1; i++) if (x[i] > X[i + 1]) falso retorno; devolver verdadero; } clasificación de vacío estático privado (int[] x) { int j, a; // Para todos los valores enteros excepto el valor más a la izquierda … para (int i = 1; i < x.length; i++) { // Get integer value a. a = x[i]; // Get index of a. This is the initial insert position, which is // used if a is larger than all values in the sorted section. j = i; // While values exist to the left of a's insert position and the // value immediately to the left of that insert position is // numerically greater than a's value ... while (j > 0 &&x[j – 1] > a) { // Desplazar valor a la izquierda — x[j – 1] — una posición a su derecha — // x[j]. X[j] =x[j – 1]; // Actualizar la posición de inserción a la posición original del valor desplazado // (una posición a la izquierda). j–; } // Insertar a en la posición de inserción (que es la posición de inserción // inicial o la posición de inserción final), donde a es mayor que // o igual a todos los valores a su izquierda. X[j] = un; } afirmar isSorted(x): «matriz no ordenada»; } }El Listado 4 presenta un método auxiliar sort() que utiliza el algoritmo de clasificación por inserción para ordenar una matriz de valores enteros. He usado afirmar para comprobar la poscondición de x que se ordena antes de que sort() regrese a su llamador. El ejemplo del Listado 4 demuestra una característica importante de las aserciones, que es que normalmente son costosas de ejecutar. Por este motivo, las aserciones suelen estar deshabilitadas en el código de producción. En el Listado 4, isSorted() debe escanear toda la matriz, lo que puede llevar mucho tiempo en el caso de una matriz larga. Afirmaciones versus excepciones en Java Los desarrolladores usan aserciones para documentar situaciones lógicamente imposibles y detectar errores en su lógica de programación. En tiempo de ejecución, una aserción habilitada alerta al desarrollador sobre un error lógico. El desarrollador refactoriza el código fuente para corregir el error lógico y luego vuelve a compilar este código. Los desarrolladores utilizan el mecanismo de excepción de Java para responder a errores de tiempo de ejecución no fatales, como quedarse sin memoria. Dichos errores pueden ser causados ​​por factores ambientales, como un archivo que no existe, o por un código mal escrito, como un intento de dividir por 0. A menudo se escribe un controlador de excepciones para recuperarse del error sin problemas, de modo que el programa pueda continuar ejecutándose. .Las afirmaciones no sustituyen a las excepciones. A diferencia de las excepciones, las aserciones no admiten la recuperación de errores (las aserciones generalmente detienen la ejecución del programa inmediatamente; AssertionError no debe detectarse); a menudo están deshabilitados en el código de producción; y normalmente no muestran mensajes de error fáciles de usar (aunque esto no es un problema con la afirmación). Es importante saber cuándo usar excepciones en lugar de aserciones. Cuándo usar excepciones Supongamos que ha escrito un método sqrt() que calcula la raíz cuadrada de su argumento. En un contexto de números no complejos, es imposible sacar la raíz cuadrada de un número negativo. Por lo tanto, se utiliza una aserción para hacer fallar el método si el argumento es negativo. Considere el siguiente fragmento de código: public double sqrt(double x) { afirmar x >= 0 : «x es negativo»; // … }No es apropiado utilizar una aserción para validar un argumento en este método público. Una afirmación tiene como objetivo detectar errores en la lógica de programación y no proteger un método de argumentos erróneos. Además, si las afirmaciones están desactivadas, no hay forma de abordar el problema de un argumento negativo. Es mejor lanzar una excepción, como sigue: public double sqrt(double x) { if (x < 0) throw new IllegalArgumentException("x is negative"); // ... }The developer might choose to have the program handle the illegal argument exception, or simply propagate it out of the program where an error message is displayed by the tool running the program. When they read the error message, the developer can fix whatever code led to the exception.You might have noticed a subtle difference between the assertion and the error-detection logic. The assertion tests x >= 0, mientras que la lógica de detección de errores prueba x < 0. La afirmación es optimista: suponemos que el argumento es correcto. Por el contrario, la lógica de detección de errores es pesimista: suponemos que el argumento no es correcto. Las aserciones documentan la lógica correcta, mientras que las excepciones documentan el comportamiento incorrecto en tiempo de ejecución. Conclusión En este tutorial, ha aprendido a utilizar aserciones para documentar la lógica correcta del programa. También ha aprendido por qué las aserciones no reemplazan las excepciones y ha visto un ejemplo en el que utilizar una excepción sería más eficaz. Copyright © 2024 IDG Communications, Inc.