Para entender lo que significa "null" en Java, veamos una analogía con los números: el número 0 simboliza la ausencia de algo, y "null" significa lo mismo en lo que respecta a los tipos de datos de referencia. Si un campo de un tipo de referencia (como String, Object, o StringBuilder) no se asigna explícitamente un valor, entonces, por analogía con los tipos primitivos, recibe un valor predeterminado, y ese valor es "null":

Código Salida en consola
public class Solution {

    public static int i;
    public static String s;

    public static void main(String[] args) {
        System.out.println(i);
        System.out.println(s);
    }
}
0
null

Pero si declaras un arreglo así:

String[] strings = new String[12];

se creará un arreglo que contiene 12 elementos, y todos ellos serán "null":

Código Salida en consola
public class Solution {
    public static void main(String[] args) {
        String[] strings = new String[12];

        for (int i = 0; i < strings.length; i++) {
            System.out.println("Element " + i + ":" + strings[i]);
        }
    }
}
Elemento 0: null
Elemento 1: null
Elemento 2: null
Elemento 3: null
Elemento 4: null
Elemento 5: null
Elemento 6: null
Elemento 7: null
Elemento 8: null
Elemento 9: null
Elemento 10: null
Elemento 11: null

Como se puede ver, al concatenarse con una cadena, el valor null se convierte en la cadena "null". Sin embargo, si se llama al método toString() sobre null, como en el siguiente ejemplo:

String[] strings = null;
System.out.println(strings.toString());

se producirá una NullPointerException (hablaremos detalladamente sobre excepciones más adelante). Lo mismo sucede si se intenta llamar a cualquier otro método sobre null (la excepción son los métodos estáticos, que conocerás próximamente):

public static void main(String[] args) {
    StringBuilder sb = null;
    sb.append("test"); // This will compile, but there will be a runtime error
}

null es, entre otras cosas, una palabra clave reservada (como public o static), por lo que no se puede crear una variable, método o clase con el nombre null. Al igual que las otras palabras clave, esta palabra es sensible a mayúsculas y minúsculas (puede haber notado que escribimos null en minúsculas en todo momento). Eso significa que:

String firstName = Null; // Compilation error
String secondName = NULL; // Compilation error
String fullName = null; // This will compile

Veamos qué más se puede y no se puede hacer con null:

  • Se puede asignar null a cualquier referencia:

    StringBuilder sb = null;
  • null se puede convertir a cualquier tipo de referencia:

    String s = (String) null; // This will compile, but doing this doesn't make any sense :)
  • null no se puede asignar a una variable primitiva:

    int i = null; // This won't compile
  • Se puede comparar null usando == y !=

  • null == null devuelve verdadero

En lecciones anteriores, hablamos sobre cómo todo en Java es un objeto, y cada objeto tiene un tipo.

¿Qué podemos decir sobre null en este sentido? null es un literal de un cierto tipo, y este tipo no tiene nombre. Y dado que este tipo no tiene nombre, es imposible declarar una variable de este tipo o hacer una conversión a él. Por lo tanto, null es el único representante de este tipo sin nombre. En la práctica, podemos ignorar este tipo y pensar en null como un literal especial que se puede asignar a cualquier variable de referencia.

Cosas para recordar:

  • null es el valor predeterminado para los tipos de datos de referencia
  • null significa "sin valor"
  • Si llamamos a cualquier método en un objeto cuyo valor es null, el código se compilará pero en tiempo de ejecución obtendremos una NullPointerException.