¿Cómo es que invocar un método (estático) en una referencia nula no genera NullPointerException?

Resuelto Artjem asked hace 14 años • 5 respuestas

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 nullobjeto causa NullPointerExceptiony, sin embargo, el programa anterior no. ¿Por qué es esto? ¿No entiendo algo correctamente?

Artjem avatar Jul 21 '10 02:07 Artjem
Aceptado

test()es un staticmétodo. Un staticmiembro pertenece al tipo y no requiere una instancia para acceder.

SÓLO se debe acceder a un staticmiembro 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 staticmiembro 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 staticacceso de miembro.

Why aNull = null; 
aNull.test(); // DO NOT EVER DO THIS!
// invokes Why.test(), does NOT throw NullPointerException

Al acceder a un staticmiembro 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 statica 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 thises 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?
polygenelubricants avatar Jul 20 '2010 19:07 polygenelubricants

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.

Vlad avatar Jul 20 '2010 19:07 Vlad

Es un método estático, que le permite llamar a métodos sin crear una instancia.

JohnFx avatar Jul 20 '2010 19:07 JohnFx

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.

MrJacqes avatar Jul 20 '2010 19:07 MrJacqes