¿Cuáles son algunos ejemplos de la vida real para comprender el papel clave de las afirmaciones?
¿Cuáles son algunos ejemplos de la vida real para comprender el papel clave de las afirmaciones?
Respuestas:
Se agregaron aserciones (por medio de la palabra clave afirmar ) en Java 1.4. Se utilizan para verificar la corrección de una invariante en el código. Nunca deben activarse en el código de producción, y son indicativos de un error o mal uso de una ruta de código. Se pueden activar en tiempo de ejecución mediante la -ea
opción del java
comando, pero no se activan de forma predeterminada.
Un ejemplo:
public Foo acquireFoo(int id) {
Foo result = null;
if (id > 50) {
result = fooService.read(id);
} else {
result = new Foo(id);
}
assert result != null;
return result;
}
assert
para verificar los parámetros de métodos públicos ( docs.oracle.com/javase/1.4.2/docs/guide/lang/assert.html ). Eso debería arrojar un en Exception
lugar de matar el programa.
This convention is unaffected by the addition of the assert construct. Do not use assertions to check the parameters of a public method. An assert is inappropriate because the method guarantees that it will always enforce the argument checks. It must check its arguments whether or not assertions are enabled. Further, the assert construct does not throw an exception of the specified type. It can throw only an AssertionError.
docs.oracle.com/javase/8/docs/technotes/guides/language/...
Supongamos que se supone que debes escribir un programa para controlar una central nuclear. Es bastante obvio que incluso el error más pequeño podría tener resultados catastróficos, por lo tanto, su código debe ser libre de errores (suponiendo que la JVM esté libre de errores por el argumento).
Java no es un lenguaje verificable, lo que significa que no puede calcular que el resultado de su operación será perfecto. La razón principal de esto son los punteros: pueden apuntar a cualquier parte o en ninguna parte, por lo tanto, no se puede calcular que tengan este valor exacto, al menos no dentro de un rango razonable de código. Dado este problema, no hay forma de demostrar que su código es correcto en su conjunto. Pero lo que puede hacer es demostrar que al menos encuentra cada error cuando sucede.
Esta idea se basa en el paradigma de diseño por contrato (DbC): primero define (con precisión matemática) lo que se supone que debe hacer su método y luego lo verifica probándolo durante la ejecución real. Ejemplo:
// Calculates the sum of a (int) + b (int) and returns the result (int).
int sum(int a, int b) {
return a + b;
}
Si bien es bastante obvio que funciona bien, la mayoría de los programadores no verán el error oculto dentro de este (pista: el Ariane V se bloqueó debido a un error similar). Ahora DbC define que siempre debe verificar la entrada y salida de una función para verificar que funcionó correctamente. Java puede hacer esto mediante aserciones:
// Calculates the sum of a (int) + b (int) and returns the result (int).
int sum(int a, int b) {
assert (Integer.MAX_VALUE - a >= b) : "Value of " + a + " + " + b + " is too large to add.";
final int result = a + b;
assert (result - a == b) : "Sum of " + a + " + " + b + " returned wrong sum " + result;
return result;
}
Si esta función fallara alguna vez, lo notará. Sabrás que hay un problema en tu código, sabes dónde está y sabes qué lo causó (similar a Excepciones). Y lo que es aún más importante: deja de ejecutar correctamente cuando sucede para evitar que cualquier código adicional funcione con valores incorrectos y potencialmente causar daños a lo que controla.
Las excepciones de Java son un concepto similar, pero no pueden verificar todo. Si desea incluso más comprobaciones (a costa de la velocidad de ejecución), debe usar aserciones. Hacerlo hinchará su código, pero al final puede entregar un producto en un tiempo de desarrollo sorprendentemente corto (cuanto antes solucione un error, menor será el costo). Y además: si hay algún error dentro de su código, lo detectará. No hay forma de que un error se deslice y cause problemas más adelante.
Esto todavía no es una garantía para un código libre de errores, pero está mucho más cerca de eso que los programas habituales.
new IllegalArgumentException
con el mensaje? Quiero decir, aparte de tener que agregar throws
a la declaración del método y al código para administrar esa excepción en otro lugar. ¿Por qué assert
insetad de lanzar una nueva excepción? ¿O por qué no un en if
lugar de assert
? Realmente no puedo entender esto :(
a
puede ser negativa. La segunda afirmación es inútil; para valores int, siempre es el caso que a + b - b == a. Esa prueba solo puede fallar si la computadora está fundamentalmente rota. Para defenderse de esa contingencia, debe verificar la coherencia en varias CPU.
Las aserciones son una herramienta de fase de desarrollo para detectar errores en su código. Están diseñados para eliminarse fácilmente, por lo que no existirán en el código de producción. Por lo tanto, las afirmaciones no son parte de la "solución" que entrega al cliente. Son verificaciones internas para asegurarse de que las suposiciones que está haciendo sean correctas. El ejemplo más común es probar nulo. Muchos métodos se escriben así:
void doSomething(Widget widget) {
if (widget != null) {
widget.someMethod(); // ...
... // do more stuff with this widget
}
}
Muy a menudo en un método como este, el widget simplemente nunca debería ser nulo. Entonces, si es nulo, hay un error en su código en algún lugar que necesita rastrear. Pero el código anterior nunca te dirá esto. Entonces, en un esfuerzo bien intencionado para escribir código "seguro", también está ocultando un error. Es mucho mejor escribir código como este:
/**
* @param Widget widget Should never be null
*/
void doSomething(Widget widget) {
assert widget != null;
widget.someMethod(); // ...
... // do more stuff with this widget
}
De esta manera, se asegurará de detectar este error temprano. (También es útil especificar en el contrato que este parámetro nunca debe ser nulo). Asegúrese de activar las aserciones cuando pruebe su código durante el desarrollo. (Y persuadir a sus colegas para que hagan esto también es a menudo difícil, lo que me parece muy molesto).
Ahora, algunos de sus colegas se opondrán a este código, argumentando que aún debe poner el cheque nulo para evitar una excepción en la producción. En ese caso, la afirmación sigue siendo útil. Puedes escribirlo así:
void doSomething(Widget widget) {
assert widget != null;
if (widget != null) {
widget.someMethod(); // ...
... // do more stuff with this widget
}
}
De esta manera, sus colegas estarán felices de que la verificación nula esté allí para el código de producción, pero durante el desarrollo, ya no estará ocultando el error cuando el widget esté nulo.
Aquí hay un ejemplo del mundo real: una vez escribí un método que comparó dos valores arbitrarios para la igualdad, donde cualquiera de los valores podría ser nulo:
/**
* Compare two values using equals(), after checking for null.
* @param thisValue (may be null)
* @param otherValue (may be null)
* @return True if they are both null or if equals() returns true
*/
public static boolean compare(final Object thisValue, final Object otherValue) {
boolean result;
if (thisValue == null) {
result = otherValue == null;
} else {
result = thisValue.equals(otherValue);
}
return result;
}
Este código delega el trabajo del equals()
método en el caso en que thisValue no sea nulo. Pero supone que el equals()
método cumple correctamente el contrato equals()
al manejar adecuadamente un parámetro nulo.
Un colega se opuso a mi código, diciéndome que muchas de nuestras clases tienen equals()
métodos con errores que no prueban nulo, por lo que debería poner esa verificación en este método. Es discutible si esto es sabio, o si debemos forzar el error, para que podamos detectarlo y solucionarlo, pero lo aplacé a mi colega y puse un cheque nulo, que he marcado con un comentario:
public static boolean compare(final Object thisValue, final Object otherValue) {
boolean result;
if (thisValue == null) {
result = otherValue == null;
} else {
result = otherValue != null && thisValue.equals(otherValue); // questionable null check
}
return result;
}
La verificación adicional aquí, other != null
solo es necesaria si el equals()
método no puede verificar nulo como lo requiere su contrato.
En lugar de entablar un debate infructuoso con mi colega sobre la sabiduría de dejar que el código con errores permanezca en nuestra base de código, simplemente pongo dos afirmaciones en el código. Estas afirmaciones me harán saber, durante la fase de desarrollo, si una de nuestras clases no se implementa equals()
correctamente, para que pueda solucionarlo:
public static boolean compare(final Object thisValue, final Object otherValue) {
boolean result;
if (thisValue == null) {
result = otherValue == null;
assert otherValue == null || otherValue.equals(null) == false;
} else {
result = otherValue != null && thisValue.equals(otherValue);
assert thisValue.equals(null) == false;
}
return result;
}
Los puntos importantes a tener en cuenta son estos:
Las afirmaciones son solo herramientas de fase de desarrollo.
El objetivo de una afirmación es hacerle saber si hay un error, no solo en su código, sino en su base de código . (Las afirmaciones aquí en realidad marcarán errores en otras clases).
Incluso si mi colega confiara en que nuestras clases fueron escritas correctamente, las afirmaciones aquí aún serían útiles. Se agregarán nuevas clases que podrían fallar al probar null, y este método puede marcar esos errores por nosotros.
En el desarrollo, siempre debe activar las aserciones, incluso si el código que ha escrito no usa aserciones. Mi IDE está configurado para hacer esto siempre de forma predeterminada para cualquier nuevo ejecutable.
Las afirmaciones no cambian el comportamiento del código en producción, por lo que mi colega está feliz de que la verificación nula esté allí y de que este método se ejecute correctamente incluso si el equals()
método tiene errores. Estoy feliz porque detectaré cualquier equals()
método defectuoso en desarrollo.
Además, debe probar su política de aserción colocando una aserción temporal que fallará, por lo que puede estar seguro de que se le notificará, ya sea a través del archivo de registro o un seguimiento de la pila en la secuencia de salida.
Muchas buenas respuestas explican lo que hace la assert
palabra clave, pero pocas responden la pregunta real, "¿cuándo debe assert
usarse la palabra clave en la vida real?"
La respuesta: casi nunca .
Las afirmaciones, como concepto, son maravillosas. Un buen código tiene muchas if (...) throw ...
declaraciones (y a sus familiares les gusta Objects.requireNonNull
y Math.addExact
). Sin embargo, ciertas decisiones de diseño han limitado enormemente la utilidad de la assert
palabra clave en sí.
La idea principal detrás de la assert
palabra clave es la optimización prematura, y la característica principal es poder desactivar fácilmente todas las comprobaciones. De hecho, las assert
verificaciones están desactivadas por defecto.
Sin embargo, es de vital importancia que los controles invariantes continúen realizándose en producción. Esto se debe a que la cobertura de prueba perfecta es imposible, y todo el código de producción tendrá errores cuyas afirmaciones deberían ayudar a diagnosticar y mitigar.
Por lo tanto, se if (...) throw ...
debe preferir el uso de , tal como se requiere para verificar los valores de los parámetros de los métodos públicos y para el lanzamiento IllegalArgumentException
.
Ocasionalmente, uno podría verse tentado a escribir un cheque invariable que demore un tiempo indeseablemente largo (y se lo llama con la frecuencia suficiente para que tenga importancia). Sin embargo, dichos controles retrasarán las pruebas, lo que tampoco es deseable. Estos controles que requieren mucho tiempo generalmente se escriben como pruebas unitarias. Sin embargo, a veces puede tener sentido usarassert
por este motivo.
No lo use assert
simplemente porque es más limpio y más bonito que if (...) throw ...
(y lo digo con mucho dolor, porque me gusta limpio y bonito). Si no puede evitarlo y puede controlar cómo se inicia su aplicación, no dude en utilizarla, assert
pero siempre habilite las afirmaciones en producción. Es cierto que esto es lo que tiendo a hacer. Estoy presionando por una anotación de lombok que hará assert
que actúe más como if (...) throw ...
. Vota por eso aquí.
(Rant: los desarrolladores de JVM eran un montón de codificadores horribles y de optimización prematura. Es por eso que escuchaste sobre tantos problemas de seguridad en el complemento de Java y JVM. Se negaron a incluir comprobaciones básicas y afirmaciones en el código de producción, y seguimos paga el precio.)
catch (Throwable t)
. No hay ninguna razón para no intentar atrapar, iniciar sesión o volver a intentar / recuperar de OutOfMemoryError, AssertionError, etc.
assert
palabra clave es mala. Editaré mi respuesta para que quede más claro que me refiero a la palabra clave, no al concepto.
Este es el caso de uso más común. Supongamos que está cambiando un valor de enumeración:
switch (fruit) {
case apple:
// do something
break;
case pear:
// do something
break;
case banana:
// do something
break;
}
Mientras manejes cada caso, estás bien. Pero algún día, alguien agregará higo a su enumeración y olvidará agregarlo a su declaración de cambio. Esto produce un error que puede ser difícil de detectar, porque los efectos no se sentirán hasta después de que haya dejado la declaración de cambio. Pero si escribe su interruptor de esta manera, puede atraparlo de inmediato:
switch (fruit) {
case apple:
// do something
break;
case pear:
// do something
break;
case banana:
// do something
break;
default:
assert false : "Missing enum value: " + fruit;
}
AssertionError
si las aserciones están habilitadas ( -ea
). ¿Cuál es el comportamiento deseado en la producción? ¿Un no-op silencioso y un posible desastre más adelante en la ejecución? Probablemente no. Sugeriría un explícito throw new AssertionError("Missing enum value: " + fruit);
.
default
para que el compilador pueda advertirle sobre casos faltantes. Puede en return
lugar de break
(esto puede necesitar extraer el método) y luego manejar el caso que falta después del cambio. De esta manera obtienes tanto la advertencia como la oportunidad assert
.
Las afirmaciones se utilizan para verificar las condiciones posteriores y las condiciones previas "nunca deben fallar". El código correcto nunca debe fallar en una afirmación; cuando se disparan, deben indicar un error (con suerte en un lugar que esté cerca del lugar real del problema).
Un ejemplo de una afirmación podría ser verificar que un grupo particular de métodos se llame en el orden correcto (por ejemplo, que hasNext()
se llama antes next()
en un Iterator
).
¿Qué hace la palabra clave afirmar en Java?
Veamos el bytecode compilado.
Concluiremos que:
public class Assert {
public static void main(String[] args) {
assert System.currentTimeMillis() == 0L;
}
}
genera casi el mismo bytecode que:
public class Assert {
static final boolean $assertionsDisabled =
!Assert.class.desiredAssertionStatus();
public static void main(String[] args) {
if (!$assertionsDisabled) {
if (System.currentTimeMillis() != 0L) {
throw new AssertionError();
}
}
}
}
donde Assert.class.desiredAssertionStatus()
es true
cuando-ea
se pasa en la línea de comando, y falso de lo contrario.
Usamos System.currentTimeMillis()
para asegurarnos de que no se optimice (lo assert true;
hizo).
El campo sintético se genera de modo que Java solo necesita llamar Assert.class.desiredAssertionStatus()
una vez en el momento de la carga, y luego almacena en caché el resultado allí. Ver también: ¿Cuál es el significado de "sintético estático"?
Podemos verificar eso con:
javac Assert.java
javap -c -constants -private -verbose Assert.class
Con Oracle JDK 1.8.0_45, se generó un campo estático sintético (consulte también: ¿Cuál es el significado de "sintético estático"? ):
static final boolean $assertionsDisabled;
descriptor: Z
flags: ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC
junto con un inicializador estático:
0: ldc #6 // class Assert
2: invokevirtual #7 // Method java/lang Class.desiredAssertionStatus:()Z
5: ifne 12
8: iconst_1
9: goto 13
12: iconst_0
13: putstatic #2 // Field $assertionsDisabled:Z
16: return
y el método principal es:
0: getstatic #2 // Field $assertionsDisabled:Z
3: ifne 22
6: invokestatic #3 // Method java/lang/System.currentTimeMillis:()J
9: lconst_0
10: lcmp
11: ifeq 22
14: new #4 // class java/lang/AssertionError
17: dup
18: invokespecial #5 // Method java/lang/AssertionError."<init>":()V
21: athrow
22: return
Concluimos que:
assert
: es un concepto de lenguaje Javaassert
podría emularse bastante bien con las propiedades del sistema -Pcom.me.assert=true
para reemplazar -ea
en la línea de comando, y a throw new AssertionError()
.catch (Throwable t)
cláusula también puede detectar violaciones de afirmación? Para mí, eso limita su utilidad solo en el caso en que el cuerpo de la afirmación lleva mucho tiempo, lo cual es raro.
AssertionError
primero y volver a lanzarlo.
Un ejemplo del mundo real, de una clase Stack (de Assertion in Java Articles )
public int pop() {
// precondition
assert !isEmpty() : "Stack is empty";
return stack[--num];
}
Una aserción permite detectar defectos en el código. Puede activar las aserciones para probar y depurar mientras las deja fuera cuando su programa esté en producción.
¿Por qué afirmar algo cuando sabes que es verdad? Solo es cierto cuando todo funciona correctamente. Si el programa tiene un defecto, podría no ser cierto. Detectar esto antes en el proceso le permite saber que algo está mal.
Una assert
declaración contiene esta declaración junto con un String
mensaje opcional .
La sintaxis para una declaración de aserción tiene dos formas:
assert boolean_expression;
assert boolean_expression: error_message;
Aquí hay algunas reglas básicas que rigen dónde se deben usar las afirmaciones y dónde no se deben usar. Las afirmaciones deben usarse para:
Validación de parámetros de entrada de un método privado. NO para métodos públicos. public
Los métodos deben arrojar excepciones regulares cuando se pasan parámetros incorrectos.
En cualquier lugar del programa para garantizar la validez de un hecho que casi con certeza es cierto.
Por ejemplo, si está seguro de que solo será 1 o 2, puede usar una afirmación como esta:
...
if (i == 1) {
...
}
else if (i == 2) {
...
} else {
assert false : "cannot happen. i is " + i;
}
...
Las afirmaciones no deben usarse para:
Validación de parámetros de entrada de un método público. Dado que las aserciones no siempre se ejecutan, se debe utilizar el mecanismo de excepción regular.
Validar restricciones en algo que es ingresado por el usuario. Lo mismo que arriba.
No debe usarse para efectos secundarios.
Por ejemplo, este no es un uso apropiado porque aquí la aserción se usa por su efecto secundario de llamar al doSomething()
método.
public boolean doSomething() {
...
}
public void someMethod() {
assert doSomething();
}
El único caso en el que esto podría justificarse es cuando intenta averiguar si las aserciones están habilitadas o no en su código:
boolean enabled = false;
assert enabled = true;
if (enabled) {
System.out.println("Assertions are enabled");
} else {
System.out.println("Assertions are disabled");
}
Además de todas las excelentes respuestas proporcionadas aquí, la guía de programación oficial de Java SE 7 tiene un manual bastante conciso sobre el uso assert
; con varios ejemplos puntuales de cuándo es una buena (y, lo que es más importante, una mala) idea usar afirmaciones, y cómo es diferente de lanzar excepciones.
Assert es muy útil cuando se desarrolla. Lo usas cuando algo simplemente no puede suceder si su código funciona correctamente. Es fácil de usar y puede permanecer en el código para siempre, ya que se desactivará en la vida real.
Si existe alguna posibilidad de que la condición pueda ocurrir en la vida real, entonces debe manejarla.
Me encanta, pero no sé cómo activarlo en Eclipse / Android / ADT. Parece estar apagado incluso cuando se depura. (Hay un hilo sobre esto, pero se refiere al 'Java vm', que no aparece en la Configuración de ejecución ADT).
Aquí hay una afirmación que escribí en un servidor para un proyecto Hibernate / SQL. Un bean de entidad tenía dos propiedades booleanas efectivas, llamadas isActive e isDefault. Cada uno podría tener un valor de "Y" o "N" o nulo, que se trató como "N". Queremos asegurarnos de que el cliente del navegador esté limitado a estos tres valores. Entonces, en mis setters para estas dos propiedades, agregué esta afirmación:
assert new HashSet<String>(Arrays.asList("Y", "N", null)).contains(value) : value;
Observe lo siguiente.
Esta afirmación es solo para la fase de desarrollo. Si el cliente envía un valor incorrecto, lo detectaremos temprano y lo arreglaremos, mucho antes de llegar a la producción. Las afirmaciones son por defectos que puede detectar temprano.
Esta afirmación es lenta e ineficiente. Esta bien. Las afirmaciones son libres de ser lentas. No nos importa porque son herramientas solo de desarrollo. Esto no ralentizará el código de producción porque las aserciones estarán deshabilitadas. (Hay cierto desacuerdo sobre este punto, que trataré más adelante). Esto me lleva al siguiente punto.
Esta afirmación no tiene efectos secundarios. Podría haber probado mi valor contra un conjunto final estático no modificable, pero ese conjunto se habría mantenido en producción, donde nunca se usaría.
Esta afirmación existe para verificar el correcto funcionamiento del cliente. Entonces, cuando lleguemos a la producción, nos aseguraremos de que el cliente esté funcionando correctamente, de modo que podamos desactivar la afirmación de forma segura.
Algunas personas preguntan esto: si la afirmación no es necesaria en la producción, ¿por qué no simplemente eliminarla cuando haya terminado? Porque aún los necesitará cuando comience a trabajar en la próxima versión.
Algunas personas han argumentado que nunca debes usar afirmaciones, porque nunca puedes estar seguro de que todos los errores hayan desaparecido, por lo que debes mantenerlos disponibles incluso en producción. Por lo tanto, no tiene sentido usar la declaración de aserción, ya que la única ventaja de las afirmaciones es que puede desactivarlas. Por lo tanto, de acuerdo con este pensamiento, usted (casi) nunca debe usar afirmaciones. Estoy en desacuerdo. Ciertamente es cierto que si una prueba pertenece a la producción, no debe usar una afirmación. Pero esta prueba no pertenece a la producción. Este es para detectar un error que probablemente nunca llegue a producción, por lo que puede apagarse de manera segura cuando haya terminado.
Por cierto, podría haberlo escrito así:
assert value == null || value.equals("Y") || value.equals("N") : value;
Esto está bien solo para tres valores, pero si el número de valores posibles aumenta, la versión HashSet se vuelve más conveniente. Elegí la versión HashSet para hacer mi punto sobre la eficiencia.
HashSet
aporta ninguna ventaja de la velocidad a través de una ArrayList
. Además, las creaciones de conjunto y lista dominan el tiempo de búsqueda. Estarían bien cuando se usa una constante. Dicho todo esto, +1.
Las aserciones se usan básicamente para depurar la aplicación o se usan para reemplazar el manejo de excepciones de alguna aplicación para verificar la validez de una aplicación.
La afirmación funciona en tiempo de ejecución. Un ejemplo simple, que puede explicar todo el concepto de manera muy simple, es aquí: ¿qué hace la palabra clave de aserción en Java? (WikiAnswers).
Las aserciones están deshabilitadas por defecto. Para habilitarlos debemos ejecutar el programa con -ea
opciones (se puede variar la granularidad). Por ejemplo, java -ea AssertionsDemo
.
Hay dos formatos para usar aserciones:
assert 1==2; // This will raise an AssertionError
.assert 1==2: "no way.. 1 is not equal to 2";
esto generará un AssertionError con el mensaje que se muestra también y, por lo tanto, es mejor. Aunque la sintaxis real es assert expr1:expr2
donde expr2 puede ser cualquier expresión que devuelva un valor, la he usado con más frecuencia solo para imprimir un mensaje.Para recapitular (y esto es cierto para muchos lenguajes, no solo Java):
"afirmar" se utiliza principalmente como una ayuda de depuración por los desarrolladores de software durante el proceso de depuración. Los mensajes de afirmación nunca deberían aparecer. Muchos idiomas proporcionan una opción de tiempo de compilación que hará que se ignoren todos los "asertos", para su uso en la generación de código de "producción".
Las "excepciones" son una forma práctica de manejar todo tipo de condiciones de error, ya sea que representen o no errores lógicos, porque, si se encuentra con una condición de error tal que no puede continuar, simplemente puede "lanzarlos al aire, "desde donde sea que estés, esperando que alguien más esté listo para" atraparlos ". El control se transfiere en un solo paso, directamente desde el código que arrojó la excepción, directamente al guante del receptor. (Y el receptor puede ver el seguimiento completo de las llamadas que se han realizado).
Además, las personas que llaman a esa subrutina no tienen que verificar si la subrutina tuvo éxito: "si estamos aquí ahora, debe haber tenido éxito, porque de lo contrario habría arrojado una excepción y no estaríamos aquí ahora". Esta estrategia simple hace que el diseño de código y la depuración sean mucho, mucho más fáciles.
Las excepciones permiten convenientemente que las condiciones de error fatal sean lo que son: "excepciones a la regla". Y, para que sean manejados por una ruta de código que también es "una excepción a la regla ... " ¡fly ball! "
Las afirmaciones son cheques que pueden desconectarse. Raramente se usan. ¿Por qué?
result != null
ya que estos controles son muy rápidos y casi no hay nada que guardar.Entonces, ¿qué queda? Las comprobaciones costosas para las condiciones realmente se espera que sean ciertas. Un buen ejemplo serían los invariantes de una estructura de datos como RB-tree. En realidad, en ConcurrentHashMap
JDK8, hay algunas afirmaciones significativas para el TreeNodes
.
A veces, el cheque no es realmente costoso, pero al mismo tiempo, está bastante seguro de que pasará. En mi código, por ejemplo, hay
assert Sets.newHashSet(userIds).size() == userIds.size();
donde estoy bastante seguro de que la lista que acabo de crear tiene elementos únicos, pero quería documentarla y verificarla dos veces.
Básicamente, "afirmar verdadero" pasará y "afirmar falso" fallará. Veamos cómo funcionará esto:
public static void main(String[] args)
{
String s1 = "Hello";
assert checkInteger(s1);
}
private static boolean checkInteger(String s)
{
try {
Integer.parseInt(s);
return true;
}
catch(Exception e)
{
return false;
}
}
assert
es una palabra clave Fue introducido en JDK 1.4. Hay dos tipos de assert
s
assert
Declaraciones muy simplesassert
Declaraciones simplesPor defecto assert
, no se ejecutarán todas las declaraciones. Si una assert
declaración recibe falso, automáticamente generará un error de aserción.