una tipos tener puede pasar parámetros parametros parametro objetos objeto método ejercicios cuantos constructores con como clase java constructor null coding-style

tipos - pasar objetos como parámetros a un método o constructor java



Estilo de constructor de Java: los parámetros de verificación no son nulos (10)

Además de las respuestas dadas anteriormente que son todas válidas y razonables, creo que es bueno señalar que tal vez la comprobación de nulo no es necesaria "buena práctica". (Asumiendo que lectores que no sean OP podrían tomar la pregunta como dogmática)

Del blog de Misko Hevery sobre la capacidad de prueba: Afirmar o No a Afirmar

¿Cuáles son las mejores prácticas si tiene una clase que acepta algunos parámetros pero ninguno de ellos tiene null ?

Lo siguiente es obvio, pero la excepción es un poco inespecífica:

public class SomeClass { public SomeClass(Object one, Object two) { if (one == null || two == null) { throw new IllegalArgumentException("Parameters can''t be null"); } //... } }

Aquí las excepciones le permiten saber qué parámetro es nulo, pero el constructor ahora es bastante feo:

public class SomeClass { public SomeClass(Object one, Object two) { if (one == null) { throw new IllegalArgumentException("one can''t be null"); } if (two == null) { throw new IllegalArgumentException("two can''t be null"); } //... }

Aquí el constructor es más nítido, pero ahora el código de constructor no está realmente en el constructor:

public class SomeClass { public SomeClass(Object one, Object two) { setOne(one); setTwo(two); } public void setOne(Object one) { if (one == null) { throw new IllegalArgumentException("one can''t be null"); } //... } public void setTwo(Object two) { if (two == null) { throw new IllegalArgumentException("two can''t be null"); } //... } }

¿Cuál de estos estilos es el mejor?

¿O hay una alternativa que es más ampliamente aceptada?


Comparación de las formas de comprobar las condiciones previas en Java: Guava vs. Apache Commons vs. Spring Framework vs. Plain Java Asserts

public static void fooSpringFrameworkAssert(String name, int start, int end) { // Preconditions Assert.notNull(name, "Name must not be null"); Assert.isTrue(start < end, "Start (" + start + ") must be smaller than end (" + end + ")"); // Do something here ... } public static void fooApacheCommonsValidate(String name, int start, int end) { // Preconditions Validate.notNull(name, "Name must not be null"); Validate.isTrue(start < end, "Start (%s) must be smaller than end (%s)", start, end); // Do something here ... } public static void fooGuavaPreconditions(String name, int start, int end) { // Preconditions Preconditions.checkNotNull(name, "Name must not be null"); Preconditions.checkArgument(start < end, "Start (%s) must be smaller than end (%s)", start, end); // Do something here ... } public static void fooPlainJavaAsserts(String name, int start, int end) { // Preconditions assert null != name : "Name must not be null"; assert start < end : "Start (" + start + ") must be smaller than end (" + end + ")"; // Do something here ... }

este es un resumen de este artículo: http://www.sw-engineering-candies.com/blog-1/comparison-of-ways-to-check-preconditions-in-java


El segundo o el tercero.

Porque le dice al usuario de su API qué fue exactamente lo que salió mal.

Para menos verbosidad use Validate.notNull(obj, message) de commons-lang. Por lo tanto, su constructor se verá así:

public SomeClass(Object one, Object two) { Validate.notNull(one, "one can''t be null"); Validate.notNull(two, "two can''t be null"); ... }

Colocar el cheque en el colocador también es aceptable, con el mismo comentario de verbosidad. Si sus incubadores también tienen la función de preservar la consistencia del objeto, también puede elegir el tercero.


Las anotaciones para el análisis estático también son útiles, en adición o en lugar de las verificaciones en tiempo de ejecución.

FindBugs, por ejemplo, proporciona una anotación @NonNull.

público SomeClass (@NonNull Object one, @NonNull Object two) {


Puede usar una de las muchas bibliotecas diseñadas para facilitar las verificaciones de condiciones previas. Muchos códigos en Google Guava usan com.google.common.base.Preconditions

Métodos estáticos simples para llamar al inicio de sus propios métodos para verificar los argumentos correctos y el estado. Esto permite construcciones tales como

if (count <= 0) { throw new IllegalArgumentException("must be positive: " + count); }

para ser reemplazado por el más compacto

checkArgument(count > 0, "must be positive: %s", count);

Tiene checkNotNull que se usa ampliamente dentro de Guava . Luego puedes escribir:

import static com.google.common.base.Preconditions.checkNotNull; //... public SomeClass(Object one, Object two) { this.one = checkNotNull(one); this.two = checkNotNull(two, "two can''t be null!"); //... }

La mayoría de los métodos están sobrecargados, ya sea que no contengan ningún mensaje de error, un mensaje de error fijo o un mensaje de error con varargs.

En IllegalArgumentException vs NullPointerException

Mientras que el código original arroja IllegalArgumentException sobre argumentos null , Guava''s Preconditions.checkNotNull arroja NullPointerException lugar.

Aquí hay una cita de Effective Java 2nd Edition: Artículo 60: Favorecer el uso de excepciones estándar :

Podría decirse que todas las invociones de métodos erróneos se reducen a un argumento ilegal o un estado ilegal, pero otras excepciones se usan de forma estándar para ciertos tipos de argumentos y estados ilegales. Si un llamador pasa null en algún parámetro para el que los valores nulos están prohibidos, la convención dicta que se IllegalArgumentException NullPointerException lugar de IllegalArgumentException .

Una NullPointerException no está reservada solo para acceder a los miembros de una referencia null ; es bastante normal lanzarlos cuando un argumento es null cuando ese es un valor ilegal.

System.out.println("some string".split(null)); // throws NullPointerException


Simplemente puede tener un método que tome todos los argumentos del constructor que necesita validar. Este método arroja una excepción con un mensaje específico dependiendo de qué argumento no es válido. Su constructor llama a este método y, si pasa, inicializa los valores.


Supongo que hablas sobre el built in assert en Java. En mi opinión, no es una buena idea usarlo. Dado que se puede activar / desactivar usando parámetros de línea de comando. Por lo tanto, algunos dicen que solo es aceptable su uso en métodos privados.

¡Mis mentores me dicen que no reinvente la rueda! Su consejo es usar bibliotecas. Están (probablemente) bien diseñados y probados. Por supuesto, es su responsabilidad asegurarse de obtener una biblioteca de buena calidad.

Otros me dicen que Enterprise ppl - en algunos términos - está equivocada y usted introduce más dependencia - para tareas simples - de lo requerido. Puedo aceptar ese punto también ... Pero aquí está mi última experiencia:

Primero escribí mi propio método privado para verificar los parámetros nulos. Es aburrido y redundante. Sé que debería ponerlo en una clase de utilidad. Pero, ¿por qué debería escribirlo en primer lugar, cuando alguien ya lo ha hecho? Puedo ahorrar tiempo sin escribir pruebas unitarias y diseñar un material existente. A menos que quiera hacer ejercicio o aprender, no lo recomendaría.

Recientemente comencé a usar la guayaba de Google y encuentro que, junto con Apache commons, una vez que comiences a utilizarlos, no utilizarás solo para ese único método. Lo descubrirás y lo usarás más y más. Al final, esto hará que su código sea más corto, más legible, más consistente y más fácil de mantener.

Por cierto: Dependiendo de tus objetivos, iría con 2 o 3 usando una de las bibliotecas mencionadas arriba ...


Tendría un método de utilidad:

public static <T> T checkNull(String message, T object) { if(object == null) { throw new NullPointerException(message); } return object; }

Haría que devuelva el objeto para que pueda usarlo en asignaciones como esta:

public Constructor(Object param) { this.param = checkNull("Param not allowed to be null", param); }

EDITAR: En cuanto a las sugerencias para utilizar una biblioteca de terceros, las Precondiciones de Google en particular hacen lo anterior incluso mejor que mi código. Sin embargo, si estas son las únicas razones para incluir la biblioteca en su proyecto, dudaría. El método es muy simple.


Una alternativa para lanzar una excepción no verificada sería el uso de assert . De lo contrario, lanzaría excepciones comprobadas para que la persona que llama tenga conocimiento del hecho de que el constructor no funcionará con valores ilegales.

La diferencia entre sus dos primeras soluciones: ¿necesita un mensaje de error detallado, necesita saber qué parámetro falló o es suficiente saber que la instancia no pudo haber sido creada debido a argumentos ilegales?

Tenga en cuenta que el segundo y el tercer ejemplo no pueden informar correctamente que ambos parámetros han sido nulos.

Por cierto, yo voto por una variación de (1):

if (one == null || two == null) { throw new IllegalArgumentException( String.format("Parameters can''t be null: one=%s, two=%s", one, two)); }


Vieja pregunta; Otra respuesta nueva (ya mencionada por otro comentario, pero creo que vale la pena su propia respuesta).

Java 7 agregó java.lang.Objects.requireNonNull() a las API que todos pueden usar. Entonces, verificando todos los argumentos para nils se reduce a una lista corta como:

this.arg1 = Objects.requireNonNull(arg1, "arg1 must not be null"); this.arg2 = Objects.requireNonNull(arg2, "arg2 must not be null");

Notas al margen:

  • asegúrese de no invertir los dos argumentos; el segundo es el mensaje que se usará para el NPE que se lanza si el primer argumento es nulo (si los invierte, entonces, su cheque nunca fallará)
  • otra mejor práctica: si es posible, haga que todos los miembros de su clase sean finales (para que pueda estar seguro: cuando un objeto se ha creado correctamente, todos sus miembros no son nulos y no cambiarán con el tiempo)