library fail comando asserts java assert

fail - java assert keyword



¿Afirmar una buena práctica o no? (7)

¿Es una buena práctica usar Assert para los parámetros de función para hacer valer su validez? Estaba revisando el código fuente de Spring Framework y noté que usan mucho Assert.notNull . Aquí hay un ejemplo

public static ParsedSql parseSqlStatement(String sql) { Assert.notNull(sql, "SQL must not be null");}

Aqui hay otro más:

public NamedParameterJdbcTemplate(DataSource dataSource) { Assert.notNull(dataSource, "The [dataSource] argument cannot be null."); this .classicJdbcTemplate = new JdbcTemplate(dataSource); } public NamedParameterJdbcTemplate(JdbcOperations classicJdbcTemplate) { Assert.notNull(classicJdbcTemplate, "JdbcTemplate must not be null"); this .classicJdbcTemplate = classicJdbcTemplate; }

Para su información, The Assert.notNull (no la afirmación assert ) se define en una clase util de la siguiente manera:

public abstract class Assert { public static void notNull(Object object, String message) { if (object == null) { throw new IllegalArgumentException (message); } } }


En principio, las assertions no son tan diferentes de muchas otras comprobaciones en tiempo de ejecución.

Por ejemplo, Java limita-verifica todos los accesos a la matriz en tiempo de ejecución. ¿Esto hace las cosas un poco más lentas? Sí. ¿Es beneficioso? ¡Absolutamente! ¡Tan pronto como ocurre una violación fuera de límite, se lanza una excepción y se alerta al programador sobre cualquier posible error! El comportamiento en otros sistemas en los que los accesos a los arreglos no están controlados es MUCHO MÁS IMPREDECIBLE. (a menudo con consecuencias desastrosas).

Las afirmaciones, ya sea que use el soporte de biblioteca o de idioma, son similares en espíritu. Hay costos de rendimiento, pero vale la pena. De hecho, las afirmaciones son aún más valiosas porque son explícitas y comunican conceptos de nivel superior.

Utilizado de forma adecuada, el costo de rendimiento se puede minimizar y el valor, tanto para el cliente (que detectará las violaciones de los contratos más pronto que tarde) como para los desarrolladores (porque el contrato es autoejecutable y autodocumentado ), se maximiza.

Otra forma de verlo es pensar en aserciones como "comentarios activos". No se puede argumentar que los comentarios son útiles, pero son PASIVOS; computacionalmente no hacen nada. Al formular algunos conceptos como afirmaciones en lugar de comentarios, se vuelven ACTIVOS. De hecho, deben mantenerse en tiempo de ejecución; las violaciones serán atrapadas.

Ver también: los beneficios de programar con aserciones


En sistemas muy grandes y mal diseñados / mantenidos, si busca mejorar la predictibilidad en métodos que son, digamos, 6000 líneas de largo y nadie en la empresa los entiende más, puede ser valioso usar la palabra clave assert para generar entornos de desarrollo. explotar, revelando errores. Pero si implementara esas afirmaciones en producción, podría cortocircuitar un parche que, aunque horriblemente concebido, resolvió un problema. Desea reparar ese parche malo descubriéndolo en el entorno de desarrollo, no en la producción. Por lo tanto, activará las afirmaciones durante el desarrollo y las desactivará en producción.

Otro uso válido de la palabra clave assert en el momento del desarrollo es insertar comprobaciones de validez en algoritmos que deben ejecutarse en tiempos de milisegundos y que están lo suficientemente aislados de llamadores imprevisibles o no probados. Es posible que no pueda permitirse conservar el control de validez en producción en tal caso, aunque sigue siendo muy útil en el desarrollo. Por otro lado, si la fuente de los parámetros que está validando es impredecible o podría serlo (si está determinada en parte por la entrada del usuario, por ejemplo), probablemente nunca pueda darse el lujo de saltear el cheque, incluso en producción, y debería tomar el golpe de rendimiento como un costo de hacer negocios. (En este último caso, probablemente no desee utilizar una afirmación). Pero debe optar por afirmar que elimina una verificación de validez en el tiempo de producción solo después de que el perfil le dice que simplemente no puede pagar los gastos generales.


Esas afirmaciones son provistas por la biblioteca y no son lo mismo que la palabra clave assert incorporada.

Aquí hay una diferencia: las afirmaciones no se ejecutan por defecto (deben estar habilitadas con el parámetro -ea ), mientras que las aserciones proporcionadas por la clase Assert no se pueden deshabilitar.

En mi opinión (por lo que vale), este es un método tan bueno como cualquiera para validar parámetros. Si hubiera utilizado aserciones integradas como lo implica el título de la pregunta, habría argumentado en contra en base a que las verificaciones necesarias no deberían ser removibles. Pero de esta manera es solo una abreviatura de:

public static ParsedSql parseSqlStatement(String sql) { if (sql == null) throw new IllegalArgumentException("SQL must not be null"); ... }

... que siempre es una buena práctica hacer en los métodos públicos.

El estilo incorporado de las afirmaciones es más útil para situaciones en las que una condición siempre debería ser cierta o para métodos privados. La guía de idioma que presenta afirmaciones tiene algunas buenas pautas que son básicamente lo que acabo de describir.



Sí, es una buena práctica.

En el caso de Spring, es particularmente importante porque las comprobaciones validan la configuración de propiedades, etc., que normalmente provienen de archivos de cableado XML. En otras palabras, están validando la configuración de la aplicación web. Y si alguna vez realiza un desarrollo serio basado en Spring, esas comprobaciones de validación le ahorrarán horas de depuración cuando cometa un error de configuración tonto.

Pero tenga en cuenta que hay una GRAN diferencia entre una clase de biblioteca llamada Assert y la palabra clave Java assert que se utiliza para definir una aserción de Java. La última forma de aserciones se puede desactivar en el momento del lanzamiento de la aplicación, y NO se debe usar para las comprobaciones de validación de los argumentos que siempre desee que ocurran. Claramente, los diseñadores de Spring piensan que sería una mala idea desactivar los cheats de la configuración de la aplicación de webapp ... y yo estoy de acuerdo.

ACTUALIZAR

En Java 7 (y posterior), la clase java.util.Objects proporciona un método de conveniencia requireNonNull para probar si un argumento es null y generar una excepción. Lo usas así:

SomeType t = ... SomeType tChecked = Objects.requireNonNull(t);

o

SomeType tChecked = Objects.requireNonNull(t, "t should be non-null");

Sin embargo, tenga en cuenta que este método aumenta NullPointerException lugar de IllegalArgumentException .


Según la java.sun.com/j2se/1.4.2/docs/guide/lang/assert.html de Sun sobre aserciones, no debe usar aserciones para verificar los argumentos en métodos públicos.

La verificación de los argumentos suele ser parte de las especificaciones publicadas (o contrato) de un método, y estas especificaciones deben obedecerse si las aserciones están habilitadas o deshabilitadas.


Si, es una buena idea. Estás imponiendo la contratación de la interfaz o clase. Si hay una violación del contrato, quiere detectarlo lo antes posible. Cuanto más espere, más impredecibles serán los resultados y más difícil será diagnosticar.

Cuando se marca explícitamente de esta manera, también debe proporcionar un mensaje de información que cuando se visualiza en un archivo de registro puede proporcionar un contexto útil para ayudar a encontrar la causa raíz o incluso para darse cuenta de que ha asumido incorrectamente el contrato.