Pregunta

Me pregunto por qué la palabra clave afirmar está tan infrautilizada en Java. Casi nunca los he visto usados, pero creo que son una gran idea. Ciertamente prefiero la brevedad de:

assert param != null : "Param cannot be null";

a la verbosidad de:

if (param == null) {
    throw new IllegalArgumentException("Param cannot be null");
}

Mi sospecha es que están infrautilizados porque

  • Llegaron relativamente tarde (Java 1.4), momento en el cual muchas personas ya habían establecido su estilo / hábito de programación Java
  • Están desactivados en tiempo de ejecución por defecto
¿Fue útil?

Solución

Las

afirmaciones son, en teoría, para probar invariantes , suposiciones de que debe ser verdadero para que el código se complete correctamente.

El ejemplo que se muestra es la prueba de entrada válida, que no es un uso típico para una aserción porque, en general, es suministrada por el usuario.

Las afirmaciones generalmente no se usan en el código de producción porque hay una sobrecarga y se supone que las situaciones en las que fallan los invariantes se han detectado como errores de codificación durante el desarrollo y las pruebas.

Su punto sobre ellos llegando "tarde" a Java también es una razón por la que no se ven más ampliamente.

Además, los marcos de prueba de unidad permiten que parte de la necesidad de afirmaciones programáticas sea externa al código que se está probando.

Otros consejos

Es un abuso de afirmaciones usarlas para probar la entrada del usuario. Lanzar una IllegalArgumentException en una entrada no válida es más correcto, ya que permite que el método de llamada detecte la excepción, muestre el error y haga lo que sea necesario (solicite la entrada nuevamente, salga, lo que sea).

Si ese método es un método privado dentro de una de sus clases, la afirmación está bien, porque solo está tratando de asegurarse de que no está pasando accidentalmente un argumento nulo. Usted prueba con afirmaciones activadas, y cuando ha probado todas las rutas y no ha activado la afirmación, puede desactivarlas para no desperdiciar recursos en ellas. También son útiles como comentarios. Una afirmar al comienzo de un método es una buena documentación para los mantenedores de que deben seguir ciertas condiciones previas, y una afirmar al final con una condición posterior documenta cuál debería ser el método obra. Pueden ser tan útiles como los comentarios; más aún, porque con las afirmaciones activadas, en realidad PRUEBAN lo que documentan.

Las aserciones son para probar / depurar, no para verificar errores, por lo que están desactivadas de forma predeterminada: para disuadir a las personas de usar aserciones para validar la entrada del usuario.

De Programación con aserciones

  

Por defecto, las aserciones están deshabilitadas en tiempo de ejecución. Dos modificadores de línea de comandos le permiten activar o desactivar selectivamente las aserciones.

Esto significa que si no tiene un control completo sobre el entorno de tiempo de ejecución, no puede garantizar que incluso se invoque el código de aserción. Las afirmaciones están destinadas a ser utilizadas en un entorno de prueba, no para el código de producción. No puede reemplazar el manejo de excepciones con aserciones porque si el usuario ejecuta su aplicación con aserciones deshabilitadas (el predeterminado ), todo su código de manejo de errores desaparece.

En "Efectivo Java", Joshua Bloch sugirió (en el tema "Verificar parámetros de validez") que (algo así como una regla simple para adoptar), para los métodos públicos, validaremos los argumentos y arrojaremos la excepción necesaria si se encuentra inválido, y para métodos no públicos (que no están expuestos y usted, como usuario de ellos, debe garantizar su validez), podemos usar la afirmación en su lugar.

yc

@Don, está frustrado de que la aserción esté desactivada de forma predeterminada. También lo estaba, y así escribí este pequeño complemento javac que los alinea (es decir, emite el bytecode para if (! Expr) throw Ex en lugar de este tonto bytecode de aserción.

Si incluye fa.jar en su ruta de clase mientras compila código Java, hará su magia y luego dirá

Note: %n assertions inlined.

@see http://smallwiki.unibe.ch/adriankuhn/javacompiler/forceassertions y, alternativamente, en github https://github.com/akuhn/javac

No estoy seguro de por qué te molestarías en escribir afirmaciones y luego reemplazarlas con una declaración de condición estándar si es así, ¿por qué no simplemente escribir las condiciones como si en primer lugar?

Las afirmaciones son solo para pruebas, y tienen dos efectos secundarios: binarios más grandes y rendimiento degradado cuando están habilitados (¡por eso puedes desactivarlos!)

Las afirmaciones no deben usarse para validar las condiciones porque eso significa que el comportamiento de su aplicación es diferente en tiempo de ejecución cuando las afirmaciones están habilitadas / deshabilitadas, ¡lo cual es una pesadilla!

Las afirmaciones son útiles porque:

  • detectar errores de PROGRAMACIÓN anticipadamente
  • código de documento usando código

Piense en ellos como autovalidación de código. Si fallan, significa que su programa está roto y debe detenerse. ¡Siempre enciéndalos mientras prueba la unidad!

En El programador pragmático incluso recomiendan dejarlos correr en producción.

  

Deje las afirmaciones activadas

     

Use aserciones para prevenir lo imposible.

Tenga en cuenta que las aserciones arrojan AssertionError si fallan, por lo que no quedan atrapadas por catch Exception.

Las afirmaciones son muy limitadas: solo puede probar condiciones booleanas y debe escribir el código para un mensaje de error útil cada vez. Compare esto con la afirmación de JUnit () que permite generar un mensaje de error útil a partir de las entradas e incluso mostrar las dos entradas una al lado de la otra en el IDE en un corredor JUnit.

Además, no puede buscar aserciones en ningún IDE que haya visto hasta ahora, pero cada IDE puede buscar invocaciones de métodos.

De hecho, llegaron a Java 1.4

Creo que el problema principal es que cuando codifica en un entorno en el que no administra directamente las opciones jvm por sí mismo, como en los servidores eclipse o J2EE (en ambos casos, es posible cambiar las opciones jvm, pero debe buscar profundamente encontrar dónde se puede hacer), es más fácil (quiero decir, requiere menos esfuerzo) usar if y excepciones (o peor, no usar nada).

Como han dicho otros: las afirmaciones no son apropiadas para validar la entrada del usuario.

Si le preocupa la verbosidad, le recomiendo que consulte una biblioteca que escribí: https: // bitbucket .org / cowwoc / requisitos / . Le permitirá expresar estas comprobaciones con muy poco código e incluso generará el mensaje de error en su nombre:

requireThat("name", value).isNotNull();

y si insiste en usar aserciones, también puede hacer esto:

assertThat("name", value).isNotNull();

El resultado se verá así:

java.lang.NullPointerException: name may not be null

tl; dr

  • Sí, use pruebas de afirmación en producción donde tenga sentido.
  • Utilice otras bibliotecas ( JUnit , AssertJ , Hamcrest , etc.) en lugar de la función incorporada afirmar si lo desea.

La mayoría de las otras respuestas en esta página empujan la máxima "Las aserciones generalmente no se usan en el código de producción". Si bien es cierto en aplicaciones de productividad como un procesador de texto o una hoja de cálculo, en aplicaciones comerciales personalizadas donde Java se usa con tanta frecuencia, las pruebas de afirmación en producción son extremadamente útiles y comunes.

Como muchas máximas en el mundo de la programación, lo que comienza cierto en un contexto es mal interpretado y luego mal aplicado en otros contextos.

Aplicaciones de productividad

Esta máxima de " Las aserciones generalmente no se usan en el código de producción ”, aunque común, es incorrecta.

Las pruebas de afirmación formalizadas se originaron con aplicaciones como un procesador de textos como Microsoft Word o una hoja de cálculo como Microsoft Excel . Estas aplicaciones pueden invocar una serie de afirmaciones de pruebas de aserciones en cada pulsación de tecla realizadas por el usuario. Tal repetición extrema afectó severamente el rendimiento. Entonces, solo las versiones beta de dichos productos en distribución limitada tenían habilitadas las aserciones. De ahí la máxima.

Aplicaciones empresariales

En contraste, en las aplicaciones orientadas a los negocios para el ingreso de datos, la base de datos u otro procesamiento de datos, el uso de pruebas de afirmación en la producción es enormemente útil. El impacto insignificante en el rendimiento lo hace bastante práctico y común.

Probar reglas comerciales

La verificación de las reglas de su negocio en tiempo de ejecución en producción es completamente razonable, y se debe alentar. Por ejemplo, si una factura debe tener una o más líneas de pedido en todo momento, escriba una prueba de afirmación que el recuento de líneas de factura es mayor que cero. Si el nombre de un producto debe tener al menos 3 caracteres o más, escriba una aserción que pruebe la longitud de la cadena. Tales pruebas no tienen un impacto significativo en el rendimiento en la producción.

Condiciones de tiempo de ejecución

Si su aplicación espera que ciertas condiciones sean siempre ciertas cuando su aplicación se ejecuta en producción, escriba esas expectativas en su código como pruebas de afirmación.

Si espera que esas condiciones puedan fallar razonablemente en ocasiones, entonces no escriba pruebas de afirmación. Quizás lanzar ciertas excepciones. Luego intente recuperarse donde sea posible.

Comprobaciones de cordura

Las comprobaciones de sanidad en el tiempo de ejecución en la producción también son completamente razonables, y deben ser alentadas . Probar algunas condiciones arbitrarias que uno no podría imaginar ser falso ha salvado mi tocino en innumerables situaciones en las que ocurrió algo extraño.

Por ejemplo, probar que redondear un centavo (0.05) al centavo resultó en un centavo (0.05) en cierta biblioteca me ayudó a ser una de las primeras personas en descubrir una falla tecnológica de punto flotante que Apple envió en su Rosetta durante la transición de PowerPC a Intel. Tal defecto llegar al público habría parecido imposible. Pero sorprendentemente, la falla se había escapado del aviso del proveedor de origen, Transitive y Apple, y de los desarrolladores de acceso temprano que probaron las versiones beta de Apple.

(Por cierto, debo mencionar ... nunca use

scroll top