2012-04-10 20 views
16
public class Main 
{ 
    public static void main(String []ar) 
    { 
     A m = new A(); 
     System.out.println(m.getNull().getValue()); 
    } 
} 

class A 
{ 
    A getNull() 
    { 
     return null; 
    } 

    static int getValue() 
    { 
     return 1; 
    } 
} 

Ich bin in einem SCJP-Buch auf diese Frage gestoßen. Der Code gibt 1 anstelle eines NPE aus, wie zu erwarten wäre. Könnte jemand bitte den Grund dafür erklären?Warum gibt dieser Code keine NullPointerException zurück?

Antwort

18

Es verhält sich, als es die Java Language Specification nach soll:

eine Nullreferenz verwendet werden kann, eine Klasse (statisches) Variable zuzugreifen, ohne eine Ausnahme zu verursachen.

22

Grundsätzlich rufen Sie eine statische Methode , als ob es eine Instanzmethode wäre. Das gerade wird zu einem statischen Methodenaufruf aufgelöst, so ist es, als ob Sie geschrieben hatte:

A m = new A(); 
m.getNull(); 
System.out.println(A.getValue()); 

IMO die Tatsache, dass der Code überhaupt ist ein Konstruktionsfehler in Java legal ist. Es ermöglicht Ihnen, sehr irreführend, Code zu schreiben, mit Thread.sleep als Beispiel ich immer wie folgt:

Thread thread = new Thread(someRunnable); 
thread.start(); 
thread.sleep(1000); 

Welche Thread, schlafen schickt? Die aktuelle, "natürlich" ...

6

Statische Methodenaufrufe werden zur Kompilierzeit aufgelöst. Der Compiler sieht, dass getNull() einen Rückgabewert vom Typ A hat, der eine statische getValue()-Methode hat (und keine gleichnamige Instanzmethode), so dass im Bytecode der tatsächliche Rückgabewert von getNull() ignoriert wird und A.getValue() aufgerufen wird.

1

getNull-Funktion gibt ein A-Objekt zurück. getValue wird als statisch deklariert und benötigt nur class_name, wie in A.getValue(). Da getNull (tatsächlich) ein A-Objekt zurückgibt, erhalten Sie 1

1

System.out.println (m.getNull(). GetValue()); Diese Codezeile ist die gleiche wie System.out.println (A.getValue());

wie weil getValue() Methode ist statisch und und alle statischen Anruf initiieren zur Kompilierzeit in Java. Es erzeugt also keinen Fehler, wenn Sie getValue() in nicht statisch machen dies wird Fehler erzeugen, da es zur Laufzeit aufgerufen wird

+1

Dies ist falsch, 'm.getNull()' ** tut ** gerufen werden. Seht Jons Antwort. – assylias

+0

m.getNull() wird nur aufgerufen, wenn getNull nicht statisch ist. was ich bereits erwähnt habe. –

+1

Was ich meinte ist, dass 'System.out.println (m.getNull(). GetValue());' nicht äquivalent zu 'System.out.println (A.getValue());'. Es ist äquivalent zu 'm.getNull(); System.out.println (A.getValue()); '. – assylias

Verwandte Themen