¿Cómo es que invocar un método (estático) en una referencia nula no genera NullPointerException?
Escribí este programa en Java
public class Why {
public static void test() {
System.out.println("Passed");
}
public static void main(String[] args) {
Why NULL = null;
NULL.test();
}
}
Leí que invocar un método en un null
objeto causa NullPointerException
y, sin embargo, el programa anterior no. ¿Por qué es esto? ¿No entiendo algo correctamente?
test()
es un static
método. Un static
miembro pertenece al tipo y no requiere una instancia para acceder.
SÓLO se debe acceder a un static
miembro a través de una expresión de tipo. Es decir, deberías haberlo escrito de la siguiente manera:
Why.test(); // always invoke static method on the type it belongs to!
Java le permite acceder a un static
miembro a través de una expresión de referencia de objeto, pero esto es MUY engañoso, ya que NO es la semántica real de un static
acceso de miembro.
Why aNull = null;
aNull.test(); // DO NOT EVER DO THIS!
// invokes Why.test(), does NOT throw NullPointerException
Al acceder a un static
miembro a través de una expresión de referencia de objeto, solo importa el tipo declarado de referencia. Esto significa que:
- No importa si la referencia es realmente
null
, ya que no se requiere ninguna instancia. - Si la referencia no es
null
, no importa cuál sea el tipo de tiempo de ejecución del objeto, ¡ no hay envío dinámico !
Como puede ver, ocurre exactamente lo opuesto en ambos puntos, por ejemplo, el acceso de miembros. Esta es la razón por la que NUNCA se debe acceder static
a los miembros de una manera "no", porque da una apariencia muy engañosa sobre lo que realmente están haciendo.static
Preguntas relacionadas
- ¿Por qué Java no permite anular métodos estáticos? (¡la comprensión
this
es crucial!) - ¿Por qué llamar a un método estático a través de una instancia no es un error para el compilador de Java?
Los métodos estáticos no necesitan una referencia al objeto. Entonces puedes llamarlo incluso, la referencia al objeto es nula. Así es como funciona el método principal.
Intente eliminar la designación estática del objeto para ver la excepción del puntero nulo.
Es un método estático, que le permite llamar a métodos sin crear una instancia.
Debe activar las diversas advertencias en su IDE. Es probable que vea una advertencia sobre el acceso a un miembro estático de forma no estática.
Podrías hacer algo como (Why)(null).test(), solo usa (Why)(null) para obtener la clase.