Frage

Ich habe mich immer gefragt, warum die JVM Sie nicht sagen die Zeiger (oder genauer gesagt, die Variable) null ist, wenn ein NullPointerException geworfen wird.

Eine Zeilennummer ist nicht spezifisch genug, weil die Codezeile oft zahlreiche Variablen enthalten, die den Fehler verursacht haben könnte.

Gibt es einen Compiler oder JVM-Flag, die diese Ausnahmemeldungen nützlicher machen würde?

War es hilfreich?

Lösung

Es ist, weil die dereferenzieren geschieht immer, wenn kein Name verfügbar ist. Der Wert wird auf den Operandenstapel geladen wird, und wird dann an einen des Opcodes JRE übergeben, die es dereferenzieren. Allerdings ist der Operandenstapel keinen Namen mit einem Nullwert zu assoziieren hat. Alles, was es hat, ist ‚Null‘. Mit einigem cleveren Code Laufzeit-Tracking kann ein Name abgeleitet werden, aber das würde hinzufügen Overhead mit begrenztem Wert.

Aus diesem Grunde gibt es keine JRE-Option, die auf zusätzliche Informationen für Null-Zeiger-Ausnahmen verwandeln wird.

In diesem Beispiel wird die Referenz in lokalem Steckplatz 1 gespeichert, die ein lokalen Karten zu Variablennamen. Aber das dereferenzieren geschieht in der invokevirtual Anweisung, die nur einen ‚Null‘ Wert auf dem Stapel sieht, und dann löst eine Ausnahme:

15 aload_1
16 invokevirtual #5 

Ebenso gilt eine Array Last durch einen dereferenzieren gefolgt wäre, aber in diesem Fall gibt es keinen Namen für den ‚Null‘ Wert auf der Karte, nur einen Index von einem anderen Wert aus.

76 aload    5
78 iconst_0
79 aaload
80 invokevirtual #5

Sie können nicht die Namen zuweisen statisch entweder zu jedem Befehl - in diesem Beispiel eine Menge Bytecode erzeugt, aber man kann sehen, dass die dereferenzieren Anweisung entweder objA oder objB erhalten, und Sie würden es verfolgen müssen dynamisch die berichten Recht ein, da beide Variablen fließen zu gleichen dereferenzieren Anweisung:

(myflag ? objA : objB).toString()

Andere Tipps

Wenn Sie den Code JIT, es ist nur nativen Zeiger Mathematik, und wenn irgendein Zeiger in den nativen Code null wirft es die Ausnahme. Es hätte verheerende Auswirkungen auf die Leistung haben, dass die Baugruppe wieder auf die ursprüngliche Variable umzukehren und die JIT Berücksichtigung optimiert den generierten Code auf unterschiedlichen Ebenen, oft auch gar nicht möglich.

Wenn Sie die Zeile in mehrere Zeilen, anstatt, mehrere Verfahren zu brechen fordert eine Zeile, oder wenn Sie einen Haltepunkt in der Zeile gesetzt und mit einem Debugger durch die Linie Schritt, können Sie herausfinden, welche Referenz ziemlich leicht null ist.

Wenn

  

Eine Zeilennummer ist nicht spezifisch genug   da die Leitung säumige kann oft   zahlreiche Variablen enthalten, die konnte   verursacht hat, den Fehler.

dann schlage ich vor:

  1. Das Aufbrechen dieser Linie in mehr als eine Zeile und weisen die möglichen NullPointerException erzeugenden Werte zu temporären Variablen.
  2. Verwenden Sie einen Debugger und Schritt über jeden Methodenaufruf, bis Sie die Ursache für das Problem zu finden.

Dies ist leider nur die Art und Weise Java funktioniert.

Wenn dies „Ihr“ Code dann einfach Schnipsel hinzufügen wie

if (foo == null) {
  throw new NullPointerException("foo == null");
}

rechts nach foo zuweisen. Wenn foo ist ein Parameter, dann sofort der Methode Körper zu Beginn überprüfen und werfen Illegal statt.

Dies sollte Ihnen helfen, Fragen zu klären.

Sie können einen Haltepunkt auf der Null-Zeiger-Ausnahme in Eclipse hinzufügen beim Debuggen die genaue Ursache der Ausnahme zu erhalten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top