java división - Evitando!=Declaraciones nulas




excepción division (25)

Uso object != null mucho para evitar NullPointerException .

¿Hay una buena alternativa a esto?

Por ejemplo:

if (someobject != null) {
    someobject.doCalc();
}

Esto evita una NullPointerException , cuando se desconoce si el objeto es null o no.

Tenga en cuenta que la respuesta aceptada puede estar desactualizada, consulte https://.com/a/2386013/12943 para obtener un enfoque más reciente.


Answers

Probablemente la mejor alternativa para Java 8 o más reciente es usar la Optionalclase.

Optional stringToUse = Optional.of("optional is there");
stringToUse.ifPresent(System.out::println);

Esto es especialmente útil para largas cadenas de posibles valores nulos. Ejemplo:

Optional<Integer> i = Optional.ofNullable(wsObject.getFoo())
    .map(f -> f.getBar())
    .map(b -> b.getBaz())
    .map(b -> b.getInt());

Ejemplo de cómo lanzar una excepción en nulo:

Optional optionalCarNull = Optional.ofNullable(someNull);
optionalCarNull.orElseThrow(IllegalStateException::new);

Java 7 introdujo el Objects.requireNonNullmétodo que puede ser útil cuando se debe comprobar que no haya nulidad. Ejemplo:

String lowerVal = Objects.requireNonNull(someVar, "input cannot be null or empty").toLowerCase();

Hacer esa pregunta indica que puede estar interesado en estrategias de manejo de errores. El arquitecto de tu equipo debe decidir cómo trabajar los errores. Hay varias formas de hacerlo:

  1. permitir que las Excepciones se trasladen a través de ellas: atraparlas en el 'bucle principal' o en alguna otra rutina de administración.

    • Verificar condiciones de error y manejarlas adecuadamente.

Seguro que también eche un vistazo a la Programación Orientada a Aspectos, ya que tienen formas sencillas de insertarlo if( o == null ) handleNull()en su código de bytes.


Soy un fan del código "fail fast". Pregúntese: ¿está haciendo algo útil en el caso de que el parámetro sea nulo? Si no tiene una respuesta clara para lo que su código debe hacer en ese caso ... Es decir, nunca debe ser nulo en primer lugar, luego ignórelo y permita que se lance una NullPointerException. El código de llamada tendrá tanto sentido de una NPE como lo haría una IllegalArgumentException, pero será más fácil para el desarrollador depurar y entender qué salió mal si se lanza una NPE en lugar de que su código intente ejecutar otra contingencia inesperada Lógica: lo que finalmente hace que la aplicación falle de todos modos.


He intentado el NullObjectPatternpero para mí no siempre es la mejor manera de ir. Hay ocasiones en que una "no acción" no es apropiada.

NullPointerExceptiones una excepción de Runtime que significa que es culpa de los desarrolladores y con suficiente experiencia le dice exactamente dónde está el error.

Ahora a la respuesta:

Intente hacer que todos sus atributos y sus accesores sean lo más privados posible o evite exponerlos a los clientes. Por supuesto, puede tener los valores de argumento en el constructor, pero al reducir el alcance, no permite que la clase cliente pase un valor no válido. Si necesita modificar los valores, siempre puede crear uno nuevo object. Verifica los valores en el constructor solo una vez y en el resto de los métodos puede estar casi seguro de que los valores no son nulos.

Por supuesto, la experiencia es la mejor manera de entender y aplicar esta sugerencia.

¡Byte!


public static <T> T ifNull(T toCheck, T ifNull) {
    if (toCheck == null) {
           return ifNull;
    }
    return toCheck;
}

Wow, casi odio agregar otra respuesta cuando tenemos 57 formas diferentes de recomendar el NullObject pattern , pero creo que a algunas personas interesadas en esta pregunta les gustaría saber que hay una propuesta para Java 7 sobre la mesa para agregar "null". "Manejo seguro": una sintaxis optimizada para la lógica if-not-equal-null.

El ejemplo dado por Alex Miller se ve así:

public String getPostcode(Person person) {  
  return person?.getAddress()?.getPostcode();  
}  

El ?. significa solo desvincular el identificador izquierdo si no es nulo, de lo contrario evalúe el resto de la expresión como null . Algunas personas, como Dick Wall, miembro de Java Posse y los votantes de Devoxx, realmente aman esta propuesta, pero también hay oposición, ya que en realidad fomentará un mayor uso de null como valor centinela.

Actualización: Se proposed una proposed para un operador seguro en nulo en Java 7 en el marco de Project Coin. La sintaxis es un poco diferente a la del ejemplo anterior, pero es la misma noción.

Actualización: La propuesta del operador de seguridad nula no se convirtió en Project Coin. Por lo tanto, no verás esta sintaxis en Java 7.


El marco de las colecciones de Google ofrece una forma buena y elegante de lograr el cheque nulo.

Hay un método en una clase de biblioteca como esta:

static <T> T checkNotNull(T e) {
   if (e == null) {
      throw new NullPointerException();
   }
   return e;
}

Y el uso es (con import static ):

...
void foo(int a, Person p) {
   if (checkNotNull(p).getAge() > a) {
      ...
   }
   else {
      ...
   }
}
...

O en tu ejemplo:

checkNotNull(someobject).doCalc();

Si no se permiten valores indefinidos:

Puede configurar su IDE para advertirle sobre una posible anulación de referencia nula. Por ejemplo, en Eclipse, consulte Preferencias> Java> Compilador> Errores / Advertencias / Análisis nulo .

Si se permiten valores indefinidos:

Si desea definir una nueva API en la que los valores no definidos tengan sentido , use el Patrón de opción (puede ser familiar para los lenguajes funcionales). Tiene las siguientes ventajas:

  • Se establece explícitamente en la API si una entrada o salida existe o no.
  • El compilador le obliga a manejar el caso "indefinido".
  • La opción es una mónada , por lo que no es necesario realizar una comprobación nula detallada, simplemente use map / foreach / getOrElse o un combinador similar para usar el valor de forma segura (example) .

Java 8 tiene una clase Optional incorporada (recomendada); para versiones anteriores, hay alternativas de biblioteca, por ejemplo, la Optional Guava o la Option FunctionalJava . Pero al igual que muchos patrones de estilo funcional, el uso de Opción en Java (incluso 8) da como resultado una gran cantidad de repeticiones, que puede reducir utilizando un lenguaje JVM menos detallado, por ejemplo, Scala o Xtend.

Si tiene que lidiar con una API que podría devolver nulos , no puede hacer mucho en Java. Xtend y Groovy tienen el operador de Elvis y el operador de anulación de seguridad nula ?. , pero tenga en cuenta que esto devuelve nulo en caso de una referencia nula, por lo que simplemente "difiere" el manejo adecuado de nulo.


Este es un problema muy común para todos los desarrolladores de Java. Por lo tanto, hay soporte oficial en Java 8 para abordar estos problemas sin código desordenado.

Java 8 ha introducido java.util.Optional<T>. Es un contenedor que puede o no contener un valor no nulo. Java 8 ha brindado una forma más segura de manejar un objeto cuyo valor puede ser nulo en algunos de los casos. Está inspirado en las ideas de Haskell y Scala .

En pocas palabras, la clase opcional incluye métodos para tratar explícitamente los casos en que un valor está presente o ausente. Sin embargo, la ventaja en comparación con las referencias nulas es que la clase <T> Opcional lo obliga a pensar en el caso cuando el valor no está presente. Como consecuencia, puede evitar excepciones de puntero nulo no deseadas.

En el ejemplo anterior, tenemos una fábrica de servicios para el hogar que devuelve un identificador a varios dispositivos disponibles en el hogar. Pero estos servicios pueden o no estar disponibles / funcionales; significa que puede resultar en una NullPointerException. En lugar de agregar una ifcondición nula antes de usar cualquier servicio, envolvámoslo en <Servicio> Opcional.

ENVÍO A OPCIÓN <T>

Consideremos un método para obtener una referencia de un servicio de una fábrica. En lugar de devolver la referencia de servicio, envuélvala con Opcional. Le permite al usuario de la API saber que el servicio devuelto puede o no estar disponible / funcional, usar a la defensiva

public Optional<Service> getRefrigertorControl() {
      Service s = new  RefrigeratorService();
       //...
      return Optional.ofNullable(s);
   }

Como ve, Optional.ofNullable()proporciona una manera fácil de obtener la referencia envuelta. Hay otras formas de obtener la referencia de Opcional, ya sea Optional.empty()& Optional.of(). Uno para devolver un objeto vacío en lugar de volver a sintonizar nulo y el otro para envolver un objeto no anulable, respectivamente.

¿CUÁNTO EXACTAMENTE LO AYUDA A EVITAR UNA COMPROBACIÓN NULA?

Una vez que haya envuelto un objeto de referencia, Opcional proporciona muchos métodos útiles para invocar métodos en una referencia envuelta sin NPE.

Optional ref = homeServices.getRefrigertorControl();
ref.ifPresent(HomeServices::switchItOn);

Optional.ifPresent invoca al Consumidor dado con una referencia si no es un valor nulo. De lo contrario, no hace nada.

@FunctionalInterface
public interface Consumer<T>

Representa una operación que acepta un solo argumento de entrada y no devuelve ningún resultado. A diferencia de la mayoría de las otras interfaces funcionales, se espera que el Consumidor opere a través de efectos secundarios. Es tan limpio y fácil de entender. En el ejemplo de código anterior, HomeService.switchOn(Service)se invoca si la referencia de retención Opcional no es nula.

Usamos el operador ternario muy a menudo para verificar la condición nula y devolver un valor alternativo o valor predeterminado. Opcional proporciona otra forma de manejar la misma condición sin marcar nulo. Optional.orElse (defaultObj) devuelve defaultObj si el Opcional tiene un valor nulo. Vamos a usar esto en nuestro código de muestra:

public static Optional<HomeServices> get() {
    service = Optional.of(service.orElse(new HomeServices()));
    return service;
}

Ahora HomeServices.get () hace lo mismo, pero de una mejor manera. Comprueba si el servicio ya está inicializado o no. Si es así, devuelva lo mismo o cree un nuevo servicio nuevo. Opcional <T> .orElse (T) ayuda a devolver un valor predeterminado.

Finalmente, aquí está nuestro NPE y nuestro código nulo de verificación sin cargo:

import java.util.Optional;
public class HomeServices {
    private static final int NOW = 0;
    private static Optional<HomeServices> service;

public static Optional<HomeServices> get() {
    service = Optional.of(service.orElse(new HomeServices()));
    return service;
}

public Optional<Service> getRefrigertorControl() {
    Service s = new  RefrigeratorService();
    //...
    return Optional.ofNullable(s);
}

public static void main(String[] args) {
    /* Get Home Services handle */
    Optional<HomeServices> homeServices = HomeServices.get();
    if(homeServices != null) {
        Optional<Service> refrigertorControl = homeServices.get().getRefrigertorControl();
        refrigertorControl.ifPresent(HomeServices::switchItOn);
    }
}

public static void switchItOn(Service s){
         //...
    }
}

La publicación completa es NPE, así como el código nulo de verificación sin cargo ... ¿En serio? .


Dependiendo del tipo de objetos que esté verificando, es posible que pueda utilizar algunas de las clases en los comunes de apache, como: lang de apache commons y colecciones de apache commons

Ejemplo:

String foo;
...
if( StringUtils.isBlank( foo ) ) {
   ///do something
}

o (dependiendo de lo que necesite verificar):

String foo;
...
if( StringUtils.isEmpty( foo ) ) {
   ///do something
}

La clase StringUtils es solo una de muchas; Hay bastantes buenas clases en los comunes que no permiten una manipulación segura.

A continuación, se muestra un ejemplo de cómo puede usar la nulidad nula en JAVA cuando incluye la biblioteca de apache (commons-lang-2.4.jar)

public DOCUMENT read(String xml, ValidationEventHandler validationEventHandler) {
    Validate.notNull(validationEventHandler,"ValidationHandler not Injected");
    return read(new StringReader(xml), true, validationEventHandler);
}

Y si está utilizando Spring, Spring también tiene la misma funcionalidad en su paquete, consulte la biblioteca (spring-2.4.6.jar)

Ejemplo sobre cómo usar este classf estático de spring (org.springframework.util.Assert)

Assert.notNull(validationEventHandler,"ValidationHandler not Injected");

"Problema" común en Java de hecho.

Primero, mis pensamientos sobre esto:

Considero que es malo "comer" algo cuando se pasó NULL donde NULL no es un valor válido. Si no está saliendo del método con algún tipo de error, significa que no hubo ningún error en su método, lo cual no es cierto. Entonces, probablemente devuelva nulo en este caso, y en el método de recepción nuevamente verifique que no haya nulo, y nunca termina, y termina con "if! = Null", etc.

Por lo tanto, en mi humilde opinión, el valor nulo debe ser un error crítico que impida la ejecución adicional (es decir, donde nulo no es un valor válido).

La forma en que resuelvo este problema es la siguiente:

Primero, sigo esta convención:

  1. Todos los métodos públicos / API siempre comprueban sus argumentos para null
  2. Todos los métodos privados no verifican si es nulo, ya que son métodos controlados (solo se deja morir con la excepción de nullpointer en caso de que no se haya manejado anteriormente)
  3. Los únicos otros métodos que no verifican si son nulos son los métodos de utilidad. Son públicos, pero si los llama por alguna razón, sabe qué parámetros pasa. Esto es como tratar de hervir agua en el hervidor sin proporcionar agua ...

Y finalmente, en el código, la primera línea del método público es la siguiente:

ValidationUtils.getNullValidator().addParam(plans, "plans").addParam(persons, "persons").validate();

Tenga en cuenta que addParam () devuelve self, para que pueda agregar más parámetros para verificar.

El método se validate()activará ValidationExceptionsi alguno de los parámetros es nulo (marcado o sin marcar es más un problema de diseño / gusto, pero mi ValidationExceptionestá marcado).

void validate() throws ValidationException;

El mensaje contendrá el siguiente texto si, por ejemplo, "planes" es nulo:

" Se encontró un valor de argumento no válido nulo para el parámetro [planes] "

Como puede ver, el segundo valor en el método addParam () (cadena) es necesario para el mensaje del usuario, porque no puede detectar fácilmente el nombre de la variable pasada, incluso con la reflexión (no es el tema de esta publicación de todos modos ...).

Y sí, sabemos que más allá de esta línea ya no encontraremos un valor nulo, por lo que simplemente invocamos métodos en esos objetos de forma segura.

De esta manera, el código es limpio, fácil de mantener y legible.


Si no se permiten valores nulos

Si su método se llama externamente, comience con algo como esto:

public void method(Object object) {
  if (object == null) {
    throw new IllegalArgumentException("...");
  }

Luego, en el resto de ese método, sabrás que el object no es nulo.

Si es un método interno (que no es parte de una API), solo documente que no puede ser nulo, y eso es todo.

Ejemplo:

public String getFirst3Chars(String text) {
  return text.subString(0, 3);
}

Sin embargo, si su método simplemente pasa el valor, y el siguiente método lo pasa, etc. podría resultar problemático. En ese caso, es posible que desee comprobar el argumento como se indica arriba.

Si se permite nulo

Esto realmente depende. Si encuentro que a menudo hago algo como esto:

if (object == null) {
  // something
} else {
  // something else
}

Así que me ramifico, y hago dos cosas completamente diferentes. No hay un fragmento de código feo, porque realmente necesito hacer dos cosas diferentes dependiendo de los datos. Por ejemplo, ¿debo trabajar en la entrada o debo calcular un buen valor predeterminado?

En realidad, es raro que use el idioma " if (object != null && ... ".

Puede ser más fácil darle ejemplos, si muestra ejemplos de dónde usa normalmente el idioma.


Si usa (o planea usar) un IDE de Java como JetBrains IntelliJ IDEA , Eclipse o Netbeans o una herramienta como Findbugs, puede usar anotaciones para resolver este problema.

Básicamente, tienes @Nullable y @NotNull .

Se puede utilizar en método y parámetros, como este:

@NotNull public static String helloWorld() {
    return "Hello World";
}

o

@Nullable public static String helloWorld() {
    return "Hello World";
}

El segundo ejemplo no compilará (en IntelliJ IDEA).

Cuando usas la primera función helloWorld() en otro fragmento de código:

public static void main(String[] args)
{
    String result = helloWorld();
    if(result != null) {
        System.out.println(result);
    }
}

Ahora el compilador de IDEA de IntelliJ le dirá que la comprobación es inútil, ya que la función helloWorld() no volverá a ser null , nunca.

Usando parametro

void someMethod(@NotNull someParameter) { }

si escribes algo como:

someMethod(null);

Esto no compilará.

Último ejemplo usando @Nullable

@Nullable iWantToDestroyEverything() { return null; }

Haciendo esto

iWantToDestroyEverything().something();

Y puedes estar seguro de que esto no sucederá. :)

Es una buena manera de dejar que el compilador verifique algo más de lo que suele hacer y hacer que sus contratos sean más sólidos. Desafortunadamente, no es compatible con todos los compiladores.

En IntelliJ IDEA 10.5 y en adelante, agregaron soporte para cualquier otra implementación de @Nullable @NotNull .

Ver publicación en el blog Más flexible y configurable @ Nullable / @ NotNull anotaciones .


  • Si considera que un objeto no debe ser nulo (o es un error) use una aserción.
  • Si su método no acepta parámetros nulos, dígalo en el javadoc y use una aserción.

Debe verificar el objeto! = Null solo si desea manejar el caso donde el objeto puede ser nulo ...

Hay una propuesta para agregar nuevas anotaciones en Java7 para ayudar con los parámetros null / notnull: http://tech.puredanger.com/java7/#jsr308


Me gustan los artículos de Nat Pryce. Aquí están los enlaces:

En los artículos también hay un enlace a un repositorio Git para un Java Maybe Type que me parece interesante, pero no creo que por sí solo pueda disminuir la cantidad de códigos de verificación. Después de investigar un poco en Internet, creo que = el código nulo podría disminuir debido a un diseño cuidadoso.


  1. Nunca inicialice variables a nulo.
  2. Si (1) no es posible, inicialice todas las colecciones y matrices a colecciones / matrices vacías.

Haciendo esto en tu propio código, puedes evitar! = Cheques nulos.

La mayoría de las veces, los controles nulos parecen proteger los bucles de las colecciones o los arreglos, así que simplemente inicialícelos, no necesitará ningún control nulo.

// Bad
ArrayList<String> lemmings;
String[] names;

void checkLemmings() {
    if (lemmings != null) for(lemming: lemmings) {
        // do something
    }
}



// Good
ArrayList<String> lemmings = new ArrayList<String>();
String[] names = {};

void checkLemmings() {
    for(lemming: lemmings) {
        // do something
    }
}

Hay una pequeña sobrecarga en esto, pero vale la pena por un código más limpio y menos NullPointerExceptions.


¿Puedo contestarlo más generalmente?

Por lo general, nos enfrentamos a este problema cuando los métodos obtienen los parámetros de la forma que no esperábamos (la mala llamada es un error del programador). Por ejemplo: esperas obtener un objeto, en vez de eso obtienes un nulo. Usted espera obtener una Cadena con al menos un carácter, en lugar de obtener una Cadena vacía ...

Así que no hay diferencia entre:

if(object == null){
   //you called my method badly!

}

o

if(str.length() == 0){
   //you called my method badly again!
}

Ambos quieren asegurarse de que recibimos parámetros válidos, antes de realizar cualquier otra función.

Como se mencionó en algunas otras respuestas, para evitar los problemas anteriores, puede seguir el patrón Diseño por contrato . Por favor, consulte http://en.wikipedia.org/wiki/Design_by_contract .

Para implementar este patrón en java, puede usar anotaciones de java principales como javax.annotation.NotNull o usar bibliotecas más sofisticadas como Hibernate Validator .

Solo una muestra:

getCustomerAccounts(@NotEmpty String customerId,@Size(min = 1) String accountType)

Ahora puede desarrollar de forma segura la función principal de su método sin necesidad de verificar los parámetros de entrada, protegen sus métodos de parámetros inesperados.

Puede ir un paso más allá y asegurarse de que solo se puedan crear pojos válidos en su aplicación. (Muestra del sitio del validador de hibernación)

public class Car {

   @NotNull
   private String manufacturer;

   @NotNull
   @Size(min = 2, max = 14)
   private String licensePlate;

   @Min(2)
   private int seatCount;

   // ...
}

En lugar de un patrón de objeto nulo, que tiene sus usos, puede considerar situaciones en las que el objeto nulo es un error.

Cuando se lanza la excepción, examine el seguimiento de la pila y trabaje a través del error.


Simplemente nunca uses null. No lo permitas

En mis clases, la mayoría de los campos y las variables locales tienen valores predeterminados que no son nulos, y agrego declaraciones de contrato (aseveraciones siempre activas) en todas partes del código para asegurarme de que esto se cumpla (ya que es más sucinto y más expresivo que dejarlo) aparece como NPE y luego tiene que resolver el número de línea, etc.).

Una vez que adopté esta práctica, noté que los problemas parecían solucionarse solos. Cogió cosas mucho antes en el proceso de desarrollo solo por accidente y se dio cuenta de que tenía un punto débil ... y, lo que es más importante, ayuda a encapsular las inquietudes de los diferentes módulos, los diferentes módulos pueden "confiar" entre sí, y no dejar de ensuciar los Código con if = null elseconstructos!

Esta es una programación defensiva y resulta en un código mucho más limpio a largo plazo. Siempre desinfecte los datos, p. Ej. Aquí mediante la aplicación de estándares rígidos, y los problemas desaparecen.

class C {
    private final MyType mustBeSet;
    public C(MyType mything) {
       mustBeSet=Contract.notNull(mything);
    }
   private String name = "<unknown>";
   public void setName(String s) {
      name = Contract.notNull(s);
   }
}


class Contract {
    public static <T> T notNull(T t) { if (t == null) { throw new ContractException("argument must be non-null"); return t; }
}

Los contratos son como mini pruebas unitarias que siempre se están ejecutando, incluso en producción, y cuando las cosas fallan, sabes por qué, en lugar de un NPE aleatorio, tienes que descifrarlo.


Además de usar assertpuedes usar lo siguiente:

if (someobject == null) {
    // Handle null here then move on.
}

Esto es un poco mejor que:

if (someobject != null) {
    .....
    .....



    .....
}

Con Java 8 viene la nueva clase java.util.Optional que posiblemente resuelva algunos de los problemas. Al menos, se puede decir que mejora la legibilidad del código y, en el caso de las API públicas, el contrato de la API es más claro para el desarrollador del cliente.

Funcionan así:

Un objeto opcional para un tipo dado ( Fruit ) se crea como el tipo de retorno de un método. Puede estar vacío o contener un objeto Fruit :

public static Optional<Fruit> find(String name, List<Fruit> fruits) {
   for (Fruit fruit : fruits) {
      if (fruit.getName().equals(name)) {
         return Optional.of(fruit);
      }
   }
   return Optional.empty();
}

Ahora mire este código donde buscamos una lista de Fruit ( fruits ) para una instancia de Fruta determinada:

Optional<Fruit> found = find("lemon", fruits);
if (found.isPresent()) {
   Fruit fruit = found.get();
   String name = fruit.getName();
}

Puede utilizar el operador map() para realizar un cálculo o extraer un valor de un objeto opcional. orElse() permite proporcionar un respaldo para los valores faltantes.

String nameOrNull = find("lemon", fruits)
    .map(f -> f.getName())
    .orElse("empty-name");

Por supuesto, la verificación del valor nulo / vacío sigue siendo necesaria, pero al menos el desarrollador es consciente de que el valor podría estar vacío y el riesgo de olvidarse de la verificación es limitado.

En una API creada desde cero utilizando Optional siempre que un valor devuelto esté vacío, y devolviendo un objeto plano solo cuando no pueda ser null (convención), el código del cliente podría abandonar las comprobaciones nulas en valores de retorno de objetos simples ...

Por supuesto, Optional también podría usarse como un argumento de método, quizás una mejor manera de indicar argumentos opcionales que 5 o 10 métodos de sobrecarga en algunos casos.

Optional ofrece otros métodos convenientes, como orElse que permiten el uso de un valor predeterminado, y ifPresent que funciona con expresiones lambda .

Los invito a leer este artículo (mi fuente principal para escribir esta respuesta) en el que la NullPointerException (y en general el puntero nulo) es problemática, así como la solución (parcial) presentada por Optional están bien explicadas: Objetos opcionales de Java .


Java 7 tiene una nueva clase de utilidad java.util.Objects en la que existe un método requireNonNull() .Todo lo que hace es lanzar un NullPointerExceptionsi su argumento es nulo, pero limpia el código un poco. Ejemplo:

Objects.requireNonNull(someObject);
someObject.doCalc();

El método es más útil para checking justo antes de una asignación en un constructor, donde cada uso puede guardar tres líneas de código:

Parent(Child child) {
   if (child == null) {
      throw new NullPointerException("child");
   }
   this.child = child;
}

se convierte en

Parent(Child child) {
   this.child = Objects.requireNonNull(child, "child");
}

Para mí, esto me parece un problema bastante común que los desarrolladores junior a intermedios tienden a enfrentar en algún momento: o no saben o no confían en los contratos en los que están participando y defensivamente realizan una verificación excesiva de los nulos. Además, cuando escriben su propio código, tienden a confiar en que devuelvan nulos para indicar algo, por lo que requieren que la persona que llama compruebe si hay nulos.

Para poner esto de otra manera, hay dos instancias donde aparece la comprobación nula:

  1. Donde null es una respuesta válida en términos del contrato; y

  2. Donde no es una respuesta válida.

(2) es fácil. Utilice declaraciones de aserción (aserciones) o permita fallos (por ejemplo, NullPointerException ). Las aserciones son una característica de Java muy infrautilizada que se agregó en 1.4. La sintaxis es:

assert <condition>

o

assert <condition> : <object>

donde <condition> es una expresión booleana y <object> es un objeto cuya salida del método toString() se incluirá en el error.

Una declaración de afirmación arroja un Error ( AssertionError ) si la condición no es verdadera. Por defecto, Java ignora las aserciones. Puede habilitar aserciones pasando la opción -ea a la JVM. Puede habilitar y deshabilitar aserciones para clases individuales y paquetes. Esto significa que puede validar el código con las aserciones durante el desarrollo y la prueba, y deshabilitarlas en un entorno de producción, aunque mis pruebas han demostrado casi sin impacto en el rendimiento de las aserciones.

No usar aserciones en este caso está bien porque el código simplemente fallará, que es lo que ocurrirá si usa aserciones. La única diferencia es que, con las afirmaciones, podría suceder antes, de una manera más significativa y posiblemente con información adicional, lo que puede ayudarlo a descubrir por qué sucedió si no lo esperaba.

(1) es un poco más difícil. Si no tienes control sobre el código al que estás llamando, estás atascado. Si null es una respuesta válida, debe verificarla.

Sin embargo, si es el código que controlas (y esto suele ser el caso), entonces es una historia diferente. Evite utilizar nulos como respuesta. Con los métodos que devuelven colecciones, es fácil: devolver colecciones vacías (o matrices) en lugar de valores nulos casi todo el tiempo.

Con no-colecciones podría ser más difícil. Considera esto como un ejemplo: si tienes estas interfaces:

public interface Action {
  void doSomething();
}

public interface Parser {
  Action findAction(String userInput);
}

donde Parser toma la entrada de usuario sin formato y encuentra algo que hacer, tal vez si está implementando una interfaz de línea de comandos para algo. Ahora puede hacer que el contrato que devuelve sea nulo si no hay una acción apropiada. Eso lleva a la comprobación nula de la que estás hablando.

Una solución alternativa es nunca devolver el valor nulo y, en su lugar, utilizar el patrón de objeto nulo :

public class MyParser implements Parser {
  private static Action DO_NOTHING = new Action() {
    public void doSomething() { /* do nothing */ }
  };

  public Action findAction(String userInput) {
    // ...
    if ( /* we can't find any actions */ ) {
      return DO_NOTHING;
    }
  }
}

Comparar:

Parser parser = ParserFactory.getParser();
if (parser == null) {
  // now what?
  // this would be an example of where null isn't (or shouldn't be) a valid response
}
Action action = parser.findAction(someInput);
if (action == null) {
  // do nothing
} else {
  action.doSomething();
}

a

ParserFactory.getParser().findAction(someInput).doSomething();

que es un diseño mucho mejor porque conduce a un código más conciso.

Dicho esto, tal vez sea totalmente apropiado que el método findAction () lance una excepción con un mensaje de error significativo, especialmente en este caso en el que confía en la información del usuario. Sería mucho mejor para el método findAction lanzar una excepción que para el método de llamada explotar con una simple NullPointerException sin explicación.

try {
    ParserFactory.getParser().findAction(someInput).doSomething();
} catch(ActionNotFoundException anfe) {
    userConsole.err(anfe.getMessage());
}

O si cree que el mecanismo try / catch es demasiado feo, en lugar de hacer nada, su acción predeterminada debe proporcionar comentarios al usuario.

public Action findAction(final String userInput) {
    /* Code to return requested Action if found */
    return new Action() {
        public void doSomething() {
            userConsole.err("Action not found: " + userInput);
        }
    }
}

Este es el error más común ocurrido para la mayoría de los desarrolladores.

Tenemos varias formas de manejar esto.

Enfoque 1:

org.apache.commons.lang.Validate //using apache framework

notNull (objeto objeto, mensaje de cadena)

Enfoque 2:

if(someObject!=null){ // simply checking against null
}

Enfoque 3:

@isNull @Nullable  // using annotation based validation

Enfoque 4:

// by writing static method and calling it across whereever we needed to check the validation

static <T> T isNull(someObject e){  
   if(e == null){
      throw new NullPointerException();
   }
   return e;
}

Idealmente, las excepciones de tiempo de ejecución no se deberían lanzar. Se debe crear una excepción marcada (excepción de negocios) para su escenario. Porque si cualquiera de estas excepciones se lanza y registra, desvía al desarrollador mientras pasa por los registros. En su lugar, las excepciones comerciales no crean ese pánico y, por lo general, se ignoran al solucionar problemas de registros.





java object nullpointerexception null