¿Cuál es la solución a todos los errores NullPointerException presentes, pasados y futuros?

publicado por: Anonymous

Tengo mi programa de Java y me sale un NullPointerException y he visto otras preguntas pero son de gente con otros programas y no me sirve para mi programa y quiero dejaros aquí las 2.000 líneas de mi programa para que me solucionéis el problema pero la gente no me deja.

Mirad, mi programa es como esto

  Object a = null;
  // 500 líneas de código
  // Dentro de un bucle, dentro de un if, dentro de un for...
  a = algunaFuncionDeMilLineasQueNoTeVoyAMostrar(
     parámetrosDeLosQueNoTeDiréElValor)
  // Cerrando for, cerrando if, cerrando bucle.
  // Otras 500 líneas de código
  // Una de estas líneas lanza el NPE, pero no te diré cuál.
  a.toString();
  z.hazAlgunaCosa();
  x.haxY().hazM().cuantoFaltaParaLasVacaciones().andaMiraUnPatoQuePasaPorAhi();

¿Qué está mal? ¿Por qué no hay una solución que sirva para todos los NullPointerException (NPE) si se dan tan a menudo?

solución

La solución es (redoble de tambores)…

No usar métodos o propiedades de una variable o expresión que vale null

Si tienes una línea:

p.hacerAlgo();

y te lanza un NPE, es que al ejecutarla p vale null. Asegúrate de que tenga un valor no null antes de ejecutar la línea.

Eso es todo…

No hace falta repetir la misma pregunta un millón de veces, aunque el programa sea distinto

Está claro, ¿no? Como prometía, resuelto para siempre jamás.

Si tu línea es algo así como

p.obtenerObjeto1().obtenerObjeto2().obtenerObjeto3().hacerAlgo();

es exactamente igual, si alguno de los métodos te devuelve null, al intentar llamar a su correspondiente método el JVM lanzará el NullPointerException. La única diferencia con el ejemplo anterior es que el JVM solo te mostrará error en la línea y tendrás que averiguar tú en qué paso aparece el null.

Lo anterior cambió un poco a partir de la versión 14 del lenguaje, la cual introdujo una opción para indicarle a la JVM que nos brinde mensajes más detallados sobre el código que lanza la excepción1. Esta opción está deshabilitada por defecto por lo que para habilitarla es necesario incluir el parámetro de línea de comandos de la JVM -XX:+ShowCodeDetailsInExceptionMessages al momento de ejecutar el programa.

$ java -XX:+ShowCodeDetailsInExceptionMessages ...

¿Y ahora es cuando alguien protesta: “Pero eso no me ayuda con mi problema de que me sale un NullPointerException en mi programa que aquí te escribo2“?

La respuesta: Si hay un NullPointerException, tu problema no es el NullPointerException.

Es responsabilidad de un programador saber cómo funciona su programa y cómo se organizan los datos. No es el tipo de pregunta que se pueda descargar a StackOverflow. Si tienes un NPE, estás con uno (o más) de estos casos:

  • Estás liado por la lógica del programa y no sigue el path que tú pensabas. Solución: Encárgate de depurar tu programa

El caso típico es decir "en este método a puede ser 1 ó 2" y hacer

    Object myObj = null;
    switch (a) {
    case 1:
      myOjb = new String("Hola");
      break;
    case 2:
      myObj = new Integer(1);
    }
    myObj.toString();

Tu problema es que a vale algo que no esperabas, unido a que no programas defensivamente y no controlas los valores. Depura tu programa para solucionar el valor de a, añade un default que lance una excepción cuando el valor sea inesperado.

  • Tienes un método tan complicado que no sabes cuándo se asignan valores a la referencia. Modifica tu programa para que sea fácil de leer y entender. No hagas como los antiguos elbonios que decían "Escribir es fácil, esperamos aprender a leer algún día". Si quieres comprobar si tu programa funciona cómo esperas, usa una herramienta de depuración o genera mensajes de log para que tú puedes verificar su funcionamiento. Si necesitas a alguien de Internet para que te explique como funciona tu programa, plantéate otra profesión.

  • Tienes un problema con el API. Has seguido todos los pasos arriba comentados, y al final has encontrado que la causa del origen es que estás llamando a java.util.Collections.toArray() y te devuelve un valor null. Revisa la documentación del método, revisa los parámetros que pasas, etc. Si sigues sin encontrar la solución, ¡¡¡¡Felicidades!!!! Ahora ya tienes una pregunta que es válida para SO ("¿Por qué java.util.Collections.toArray() me devuelve null?")

  • Tienes un vector que inicialisaste de alguna forma, pero nunca lo inicialisaste internamente. hacer esto tipo1 vector[] = new tipo1[n]; No implica que el vector se llenara mágicamente de objetos de tipo1. Debes hacer un New tipo1 para cada posición del vector

Una nota más sobre arrays

Como es una confusión que aparece con bastante frecuencia, insistiremos en el último punto:

 String miArray[] = new String[10];
 System.out.println(miArray.length); // Funciona
 System.out.println(miArray[0].isEmpty()); // NullPointerException

Al crear un array de objetos, se crea el array pero no se crean los objetos. Después de la primera línea del código de arriba, tienes el objeto miArray (puedes hacer miArray.length), pero ese objeto solo contiene 10 referencias (miArray[0], miArray[1]…) a null; las instancias a las que apuntan todavía se tienen que asignar. Si no se asigna una instancia a esas referencias, al intentar invocar métodos o atributos se lanzará el NullPointerException.


1Para más información consulte la [JEP 358: Helpful NullPointerExceptions](https://openjdk.java.net/jeps/358).

2Seguido de un millar de líneas de código, y por supuesto sin ni siquiera indicar en qué línea se lanza el NPE.

Respondido por: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *