¿Cómo evito buscar nulos en Java?

10 minutos de lectura

yo suelo x != null para evitar NullPointerException. ¿Hay alguna alternativa?

if (x != null) {
    // ...
}

  • @Shervin Fomentar nulos hace que el código sea menos comprensible y menos confiable.

    – Tom Hawtin – tachuela

    2 de agosto de 2010 a las 9:17

  • No usar nulo es superior a la mayoría de las otras sugerencias aquí. Lanzar excepciones, no devolver ni permitir valores nulos. Por cierto, la palabra clave ‘afirmar’ es inútil, porque está deshabilitada de forma predeterminada. Use un mecanismo de falla siempre habilitado

    – ianpojman

    08/06/2012 a las 19:40


  • Los nulos deben evitarse en el código de alto nivel. Tony Hoare, quien inventó las referencias nulas, las llama “un error de mil millones de dólares”. Echar un vistazo aquí para algunas ideas.

    –Andrii Polunin

    04/04/2016 a las 13:05

  • Parece estar en Java 8: static Objects.isNull(Object o) docs.oracle.com/javase/8/docs/api/java/util/Objects.html

    – Robert R. Evans

    23 de junio de 2016 a las 17:02


  • El mal uso más común de nulo es que las personas devuelvan un valor nulo en lugar de una colección vacía. Eso me vuelve loco cada vez. Deja de usar valores nulos y vivirás en un mundo mejor. Además, difunde tu código con final palabra clave y vivirás en un mundo aún mejor.

    – Jacobo

    29 de junio de 2021 a las 9:22


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

Básicamente, tienes @Nullable y @NotNull.

Puede usar 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 se compilará (en IntelliJ IDEA).

Cuando usas el primero helloWorld() función en otra pieza de código:

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

Ahora el compilador IntelliJ IDEA le dirá que la verificación es inútil, ya que el helloWorld() la función no regresa nullalguna vez.

Usando el parámetro

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 puede estar seguro de que esto no sucederá. 🙂

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

En IntelliJ IDEA 10.5 y posteriores, agregaron soporte para cualquier otro @Nullable @NotNull implementaciones.

Ver entrada de blog Anotaciones @Nullable/@NotNull más flexibles y configurables.

  • @NotNull, @Nullable y otras anotaciones de nulidad son parte de JSR 305. También puede usarlos para detectar problemas potenciales con herramientas como Buscar errores.

    – Jacek S.

    8 mayo 2010 a las 16:33


  • Encuentro extrañamente molesto que el @NotNull & @Nullable las interfaces viven en el paquete com.sun.istack.internal. (Supongo que asocio com.sun con advertencias sobre el uso de una API propietaria).

    – Jonik

    30 de junio de 2011 a las 23:33

  • la portabilidad del código se vuelve nula con jetbrains. Lo pensaría dos veces (cuadrado) antes de vincularme al nivel ide. Como dijo Jacek S, son parte de JSR de cualquier manera que pensé que era JSR303 por cierto.

    –Java Ka bebé

    8 de septiembre de 2011 a las 9:39

  • Realmente no creo que usar un compilador personalizado sea una solución viable para este problema.

    – Dragón Shivan

    19 de agosto de 2012 a las 8:24

  • Lo bueno de las anotaciones, que @NotNull y @Nullable son es que se degradan agradablemente cuando el código fuente es construido por un sistema que no los entiende. Entonces, en efecto, el argumento de que el código no es portátil puede no ser válido: si usa un sistema que admite y comprende estas anotaciones, obtiene el beneficio adicional de una verificación de errores más estricta; de lo contrario, obtiene menos, pero su código aún debería construya bien, y la calidad de su programa en ejecución es LA MISMA, porque estas anotaciones no se aplicaron en tiempo de ejecución de todos modos. Además, todos los compiladores son personalizados 😉

    – Armén Michaeli

    20 de marzo de 2013 a las 9:49

  • ¿Cuál es el punto de lanzar IllegalArgumentException? Creo que NullPointerException sería más claro, y eso también se lanzaría si no realiza la verificación nula usted mismo. O usaría assert o nada en absoluto.

    – Axel

    9 de agosto de 2011 a las 16:47

  • Es poco probable que cualquier otro valor que no sea nulo sea aceptable. Podría tener IllegalArgumentException, OutOfRageException, etc. A veces esto tiene sentido. Otras veces termina creando muchas clases de excepción que no agregan ningún valor, luego simplemente usa IllegalArgumentException. No tiene sentido tener una excepción para la entrada nula y otra para todo lo demás.

    – myplacedk

    15 de agosto de 2011 a las 12:26

  • ¿Un agujero de seguridad? El JDK está lleno de código como este. Si no desea que el usuario vea stacktraces, simplemente desactívelos. Nadie dio a entender que el comportamiento no está documentado. MySQL está escrito en C, donde la desreferenciación de punteros nulos es un comportamiento indefinido, nada como lanzar una excepción.

    – fgb

    8 de abril de 2013 a las 0:39

  • throw new IllegalArgumentException("object==null")

    – Thorbjorn Ravn Andersen

    20/04/2013 a las 23:35

  • 1/2 Tengo que estar de acuerdo en que un IllegalArgumentException es mejor que un simple vainilla NPE para este tipo de situaciones. Veo un NPE como una indicación de que en algún lugar del código, algo quitó la referencia de forma insegura a una expresión que resultó ser nula (suponiendo que se cumplieron todas las condiciones previas e invariantes conocidas y declaradas). Una excepción de argumento ilegal OTH me dice que no se cumplió una condición previa conocida o invariante.

    – luis.espinal

    12 de agosto de 2016 a las 17:28


Guau, casi odio agregar otra respuesta cuando tenemos 57 formas diferentes de recomendar el NullObject patternpero creo que a algunas personas interesadas en esta pregunta les puede gustar saber que hay una propuesta sobre la mesa para que Java 7 agregue “manejo seguro nulo”: una sintaxis simplificada 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 eliminar la referencia del identificador izquierdo si no es nulo; de lo contrario, evalúe el resto de la expresión como null. Algunas personas, como el miembro de Java Posse Dick Wall y el votantes en Devoxx Me encanta esta propuesta, pero también hay oposición, con el argumento de que en realidad fomentará un mayor uso de null como valor centinela.


Actualizar: Un propuesta oficial para un operador de seguridad nula en Java 7 se ha presentado bajo Proyecto Moneda. La sintaxis es un poco diferente al ejemplo anterior, pero es la misma noción.


Actualizar: La propuesta del operador de seguridad nula no llegó al Proyecto Moneda. Por lo tanto, no verá esta sintaxis en Java 7.

  • Creo que esto está mal. Debería haber una manera de especificar que una variable dada SIEMPRE no es nula.

    – Thorbjorn Ravn Andersen

    26 de mayo de 2009 a las 11:54

  • Actualización: la propuesta no hará Java7. Ver blogs.sun.com/darcy/entry/project_coin_final_five .

    – Boris Terzic

    29 de agosto de 2009 a las 18:56

  • Idea interesante pero la elección de la sintaxis es absurda; No quiero una base de código llena de signos de interrogación clavados en cada articulación.

    – robo

    16 mayo 2012 a las 11:51

  • Este operador existe en maravillosopor lo que aquellos que quieran usarlo todavía tienen esa opción.

    – Muhd

    15 de febrero de 2013 a las 22:53


  • Esta es la idea más ingeniosa que he visto. Debe agregarse a todos los lenguajes sensibles de la sintaxis C. Prefiero “poner signos de interrogación” en todas partes que desplazarme por la pantalla llena de líneas o esquivar las “cláusulas de protección” todo el día.

    – Víctor – Reincorporar a Mónica

    1 oct 2015 a las 20:57

Si no se permiten valores indefinidos:

Puede configurar su IDE para advertirle sobre posibles desreferenciaciones nulas. Por ejemplo, en Eclipse, ver Preferencias > Java > Compilador > Errores/Advertencias/Análisis nulo.

Si se permiten valores indefinidos:

Si desea definir una nueva API donde los valores no definidos tengan sentidoutilizar el Patrón de opción (puede estar familiarizado con los lenguajes funcionales). Tiene las siguientes ventajas:

  • Se establece explícitamente en la API si existe o no una entrada o salida.
  • El compilador te obliga a manejar el caso “indefinido”.
  • La opción es una mónadapor lo que no hay necesidad de una verificación nula detallada, solo use map/foreach/getOrElse o un combinador similar para usar el valor de manera segura (ejemplo).

Java 8 tiene un incorporado Optional clase (recomendado); para versiones anteriores, existen alternativas de biblioteca, por ejemplo Guayaba‘s Optional o Java funcional‘s Option. Pero al igual que muchos patrones de estilo funcional, el uso de Option en Java (incluso 8) da como resultado bastante repetitivo, 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 valores nulos, no puedes hacer mucho en Java. Xtend y Groovy tienen la operador de elvis ?: y el operador de desreferencia de seguridad nula ?.pero tenga en cuenta que esto devuelve nulo en caso de una referencia nula, por lo que simplemente “aplaza” el manejo adecuado de nulo.

  • Creo que esto está mal. Debería haber una manera de especificar que una variable dada SIEMPRE no es nula.

    – Thorbjorn Ravn Andersen

    26 de mayo de 2009 a las 11:54

  • Actualización: la propuesta no hará Java7. Ver blogs.sun.com/darcy/entry/project_coin_final_five .

    – Boris Terzic

    29 de agosto de 2009 a las 18:56

  • Idea interesante pero la elección de la sintaxis es absurda; No quiero una base de código llena de signos de interrogación clavados en cada articulación.

    – robo

    16 mayo 2012 a las 11:51

  • Este operador existe en maravillosopor lo que aquellos que quieran usarlo todavía tienen esa opción.

    – Muhd

    15 de febrero de 2013 a las 22:53


  • Esta es la idea más ingeniosa que he visto. Debe agregarse a todos los lenguajes sensibles de la sintaxis C. Prefiero “poner signos de interrogación” en todas partes que desplazarme por la pantalla llena de líneas o esquivar las “cláusulas de protección” todo el día.

    – Víctor – Reincorporar a Mónica

    1 oct 2015 a las 20:57

Solo para esta situación –

No verificar si una variable es nula antes de invocar un método de igualdad (un ejemplo de comparación de cadenas a continuación):

if ( foo.equals("bar") ) {
 // ...
}

resultará en un NullPointerException si foo no existe

Puede evitarlo si compara su Stringes así:

if ( "bar".equals(foo) ) {
 // ...
}

  • Estoy de acuerdo, solo en esa situación. No soporto a los programadores que han llevado esto al siguiente nivel innecesario y escriben if (null != myVar)… ¡simplemente me parece feo y no sirve para nada!

    – Alex Worden

    23 de mayo de 2011 a las 18:14


  • Este es un ejemplo particular, probablemente el más utilizado, de una buena práctica general: si lo sabes, hazlo siempre. <object that you know that is not null>.equals(<object that might be null>);. Funciona para otros métodos que no sean equals si conoce el contrato y esos métodos pueden manejar null parámetros

    – Stef

    23 de septiembre de 2011 a las 1:20


  • Este es el primer ejemplo que he visto de Condiciones de Yoda eso en realidad tiene sentido

    –Erin Drummond

    30/09/2013 a las 19:37

  • NullPointerExceptions se lanzan por una razón. Se lanzan porque un objeto es nulo donde no debería estar. Es trabajo de los programadores ARREGLAR esto, no OCULTAR el problema.

    –Oliver Watkins

    12 de mayo de 2014 a las 7:49

  • Esto solo oculta el problema. ¿Qué pasa si estás usando foo ¿mas tarde? Si una variable no debe ser nula, pero lo es… su aplicación necesita obtener un NPE para que usted, como desarrollador, pueda solucionar el motivo subyacente.

    – Arnab Datta

    26 de noviembre de 2015 a las 8:57


¿Ha sido útil esta solución?