intelecto - Aserciones de Java infrautilizadas
infrautilizar (10)
@ Don, estás frustrado de que la afirmación esté desactivada por defecto. Yo también estaba, y así escribí este pequeño complemento javac que los inline (es decir, emite el bytecode para if (!expr) throw Ex
lugar de este tonto código de bytes de aserción.
Si incluye fa.jar en su classpath mientras compila el código Java, hará su magia y luego le dirá
Note: %n assertions inlined.
@ver fa.jar y alternativamente en github https://github.com/akuhn/javac
Me pregunto por qué la palabra clave assert
es tan subutilizada en Java. Casi nunca los he visto usar, 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 que muchas personas ya habían establecido su estilo / hábito de programación Java
- Se desactivan en tiempo de ejecución de forma predeterminada, ¿POR QUÉ OH POR QUÉ?
Como otros han declarado: 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/requirements/ . Le permitirá expresar estos cheques usando muy poco código, e incluso generará el mensaje de error en su nombre:
requireThat("name", value).isNotNull();
y si insiste en usar aserciones, puede hacer esto también:
assertThat("name", value).isNotNull();
La salida se verá así:
java.lang.NullPointerException: name may not be null
De hecho, llegaron a Java 1.4
Creo que el principal problema es que cuando codifica en un entorno en el que no gestiona directamente las opciones de jvm, como en los servidores eclipse o J2EE (en ambos casos, es posible cambiar las opciones de jvm, pero debe buscar profundamente para encontrar dónde se puede hacer), es más fácil (me refiero a que requiere menos esfuerzo) usar if y excepciones (o peor no usar nada).
De la programación con afirmaciones
Por defecto, las aserciones están deshabilitadas en tiempo de ejecución. Dos conmutadores de línea de comandos le permiten activar o desactivar selectivamente las afirmaciones.
Esto significa que si no tiene control total sobre el entorno de tiempo de ejecución, no puede garantizar que se invocará el código de afirmació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 (la predeterminada ), desaparecerá todo su código de manejo de errores.
En "Java efectivo", Joshua Bloch sugirió (en el tema "Comprobar parámetros de validez") que (en cierto modo, como una regla simple de adoptar), para los métodos públicos, validaremos los argumentos y lanzaremos la excepción necesaria si se encuentra inválida, y para los métodos no públicos (que no están expuestos y usted como usuario de ellos debe garantizar su validez), podemos usar la aserción en su lugar.
yc
Es un abuso de aserciones usarlos 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 capte la excepción, muestre el error y haga lo que necesite (solicite entrada de nuevo, 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. Prueba con aserciones, y cuando ha probado todas las rutas y no ha activado la aserción, puede desactivarlas para no desperdiciar recursos en ellas. También son útiles solo como comentarios. Una assert
al inicio de un método es una buena documentación para los mantenedores de que deben seguir ciertas condiciones previas, y una assert
al final con una poscondición documenta lo que el método debería estar haciendo. Pueden ser tan útiles como los comentarios; Más aún, porque con las afirmaciones en, en realidad PRUEBA lo que documentan.
Las afirmaciones son para probar / depurar, no para verificar errores, razón por la cual están desactivadas por defecto: para disuadir a las personas de usar aserciones para validar la entrada del usuario.
Las afirmaciones son útiles porque:
- atrapar errores de PROGRAMACIÓN temprano
- código de documento usando código
Piense en ellos como código de autovalidación. Si fallan debería significar que su programa está roto y debe detenerse. ¡Siempre enciéndalos mientras prueba la unidad!
En The Pragmatic Programmer incluso recomiendan dejarlos funcionar en producción.
Deja las afirmaciones activadas
Utilice las afirmaciones para evitar lo imposible.
Tenga en cuenta que las aserciones arrojan AssertionError si fallan, por lo que no son detectadas por catch Exception.
Las afirmaciones son muy limitadas: solo puede probar las condiciones booleanas y necesita escribir el código de un mensaje de error útil todo el tiempo. Compare esto con assertEquals () 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.
No estoy seguro de por qué te molestarías en escribir afirmaciones y luego reemplazarlas por una declaración de condición estándar, entonces, ¿por qué no 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 puede desactivarlos!)
Asserts no debe usarse para validar condiciones porque eso significa que el comportamiento de su aplicación es diferente en el tiempo de ejecución cuando las afirmaciones están habilitadas / deshabilitadas, lo que es una pesadilla.
Las afirmaciones son, en teoría, para probar invariants , suposiciones que deben ser ciertas 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, generalmente, es suministrada por el usuario.
Las aserciones no se usan generalmente en el código de producción porque hay una sobrecarga y se asume que las situaciones en las que los invariantes fallan se han detectado como errores de codificación durante el desarrollo y la prueba.
Su punto acerca de que ellos lleguen "tarde" a Java también es una razón por la cual no son más ampliamente vistos.
Además, los marcos de prueba de unidades permiten que parte de la necesidad de aserciones programáticas sea externa al código que se prueba.