what - Warum kann ich null in Java werfen?




what is null point exception (5)

Wenn Sie das ausführen:

public class WhatTheShoot {

    public static void main(String args[]){
        try {
            throw null;
        } catch (Exception e){
            System.out.println(e instanceof NullPointerException);
            System.out.println(e instanceof FileNotFoundException);
        }
    }
}

Die Antwort lautet:

true  
false

Was für mich ziemlich atemberaubend war. Ich hätte gedacht, dass dies einen Kompilierungsfehler ergeben würde.

Warum kann ich null in Java werfen und warum wird es auf eine NullPointerException umgestellt?

(Eigentlich weiß ich nicht, ob es ein "Upcast" ist, wenn ich null werfe)

Abgesehen von einer wirklich wirklich dummen Interviewfrage (bitte fragt das niemand in einem Interview) kann ich keinen Grund sehen throw null zu throw null . Vielleicht willst du gefeuert werden, aber das ist ... ich meine, warum sonst würde jemand throw null ?

Fun fact IntelliJ IDEA 12 sagt mir, dass meine Zeile, e instanceof NullPointerException , immer falsch ist. Was überhaupt nicht wahr ist.


Bharal ... Es sieht einen Javac Compiler Bug aus. Ich denke, es wurde in SE 5 eingeführt. Null kann jedem Referenztyp zugewiesen werden. "Der Typ von Null" ist jedoch nicht selbst ein Referenztyp. Das Programm kompiliert es, weil null einfach in Exception umgewandelt werden kann. Darüber hinaus sucht throw nach einer Objektreferenz nach der Deklaration und da null als Objektreferenz fungieren kann, zeigt es das Ergebnis an.

Der JLS Doc über werfen als:

"Eine throw-Anweisung wertet zuerst den Ausdruck aus. Wenn die Auswertung des Ausdrucks aus irgendeinem Grund abrupt abgeschlossen wird, wird der Wurf aus diesem Grund abrupt beendet. Wenn die Auswertung des Ausdrucks normal abgeschlossen wird und einen Nicht-Null-Wert V erzeugt, wird die throw-Anweisung abrupt abgeschlossen, wobei der Grund ein Wurf mit dem Wert V ist. Wenn die Auswertung des Ausdrucks normal abgeschlossen wird, wird ein Nullwert erzeugt. der Klasse NullPointerException wird erstellt und anstelle von null geworfen. Die throw-Anweisung endet dann abrupt, der Grund ist ein Wurf mit dem Wert V '. "


Es sieht so aus, als würde NullPointerException nicht als NullPointerException behandelt, aber der Versuch throw null zu throw null NullPointerException eine NullPointerException .

Mit anderen Worten, throw prüft, ob das Argument nichtnull ist und wenn es null ist, wird eine NullPointerException .

JLS 14.18 specifies dieses Verhalten:

Wenn die Auswertung des Ausdrucks normal abgeschlossen wird, indem ein Nullwert erzeugt wird, wird eine Instanz V 'der Klasse NullPointerException erstellt und anstelle von null geworfen. Die throw-Anweisung endet dann abrupt, der Grund ist ein Wurf mit dem Wert V '.


Ich weiß es nicht genau, aber ich vermute, dass "null werfen"; funktioniert nicht , und wenn es versucht wird, verursacht das Programm eine Ausnahme, und diese Ausnahme passiert (Trommelwirbel) NullPointerException ...


So darüber nachzudenken, macht es ein wenig offensichtlicher, warum das funktioniert:

try {
    Exception foo = null;
    if(false) {
        foo = new FileNotFoundException();
    } // Oops, forgot to set foo for the true case..
    throw foo;
} catch (Exception e){
    System.out.println(e instanceof NullPointerException);
    System.out.println(e instanceof FileNotFoundException);
}

Warum wird es zu einer NullPointerException upcast?

specifies :

Eine throw-Anweisung wertet zuerst den Ausdruck aus. Wenn die Auswertung des Ausdrucks aus irgendeinem Grund abrupt abgeschlossen wird, wird der Wurf aus diesem Grund abrupt beendet. Wenn die Auswertung des Ausdrucks normal abgeschlossen wird und ein Nicht-Null-Wert V erzeugt wird, wird die throw-Anweisung abrupt beendet. Der Grund hierfür ist ein throw mit Wert V. Wenn die Auswertung des Ausdrucks normal abgeschlossen wird, wird ein Nullwert erzeugt. der Klasse NullPointerException wird erstellt und anstelle von null geworfen. Die throw-Anweisung endet dann abrupt, der Grund ist ein Wurf mit dem Wert V '.

Warum kann ich null in Java werfen?

Sie können Objekte vom Typ Throwable werfen, und da null eine gültige Referenz für Throwable , lässt der Compiler dies zu.

Das sagt Neal Gafter

Obwohl null jedem Referenztyp zugewiesen werden kann, ist der Typ von null selbst kein Referenztyp. Es war unsere Absicht, dass die Anforderung, dass der Ausdruck in einer throw-Anweisung ein Referenztyp sein sollte, aus der dritten Version der JLS entfernt werden sollte, aber diese Änderung hat es nie in die veröffentlichte Version geschafft. Das ist also ein Java-Compiler-Bug, den ich in SE 5 eingeführt habe.







nullpointerexception