Hilfreiche NullPointerExceptions in Java 14

1. Übersicht

In diesem Tutorial setzen wir unsere Serie auf Java 14 fort, indem wir uns die hilfreichen NullPointerException s ansehen , eine neue Funktion, die mit dieser Version des JDK eingeführt wurde.

2. Traditionelle NullPointerException s

In der Praxis sehen oder schreiben wir häufig Code, der Methoden in Java verkettet. Wenn dieser Code jedoch eine NullPointerException auslöst , kann es schwierig werden zu wissen, woher die Ausnahme stammt.

Nehmen wir an, wir möchten die E-Mail-Adresse eines Mitarbeiters herausfinden:

String emailAddress = employee.getPersonalDetails().getEmailAddress().toLowerCase();

Wenn der Mitarbeiter Objekt, getPersonalDetails () oder getEmailAddress () ist null, führt die JVM eine Nullpointer :

Exception in thread "main" java.lang.NullPointerException at com.baeldung.java14.npe.HelpfulNullPointerException.main(HelpfulNullPointerException.java:10)

Was ist die Hauptursache für die Ausnahme? Es ist schwierig zu bestimmen, welche Variable null ist, ohne einen Debugger zu verwenden. Darüber hinaus druckt die JVM nur die Methode, den Dateinamen und die Zeilennummer aus, die die Ausnahme verursacht haben .

Im nächsten Abschnitt werden wir uns ansehen, wie Java 14 über JEP 358 dieses Problem löst.

3. Hilfreiche NullPointerException s

SAP implementierte 2006 hilfreiche NullPointerException s für ihre kommerzielle JVM. Sie wurde im Februar 2019 als Erweiterung für die OpenJDK-Community vorgeschlagen und wurde bald darauf zu einem JEP. Infolgedessen wurde das Feature im Oktober 2019 für die Veröffentlichung von JDK 14 fertiggestellt und erweitert .

Im Wesentlichen zielt JEP 358 darauf ab, die Lesbarkeit von NullPointerException s, die von JVM generiert werden, zu verbessern , indem beschrieben wird, welche Variable null ist .

358 JEP bringt eine detaillierte Nullpointer Nachricht durch die Beschreibung von null Variable neben der Methode, die Dateinamen und die Zeilennummer. Es funktioniert durch Analysieren der Bytecode-Anweisungen des Programms. Daher kann genau bestimmt werden, welche Variable oder welcher Ausdruck null war .

Am wichtigsten ist, dass die detaillierte Ausnahmemeldung in JDK 14 standardmäßig deaktiviert ist . Um es zu aktivieren, müssen wir die Befehlszeilenoption verwenden:

-XX:+ShowCodeDetailsInExceptionMessages

3.1. Detaillierte Ausnahmemeldung

Lassen Sie uns den Code erneut ausführen, wobei das Flag ShowCodeDetailsInExceptionMessages aktiviert ist:

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.toLowerCase()" because the return value of "com.baeldung.java14.npe.HelpfulNullPointerException$PersonalDetails.getEmailAddress()" is null at com.baeldung.java14.npe.HelpfulNullPointerException.main(HelpfulNullPointerException.java:10)

Dieses Mal wissen wir aus den zusätzlichen Informationen, dass die fehlende E-Mail-Adresse der persönlichen Daten des Mitarbeiters unsere Ausnahme verursacht. Das durch diese Verbesserung gewonnene Wissen kann uns beim Debuggen Zeit sparen.

JVM setzt die detaillierte Ausnahmemeldung aus zwei Teilen zusammen. Der erste Teil stellt die fehlgeschlagene Operation dar, eine Folge davon, dass eine Referenz null ist , während der zweite Teil den Grund für die Nullreferenz angibt :

Cannot invoke "String.toLowerCase()" because the return value of "getEmailAddress()" is null

Um die Ausnahmemeldung zu erstellen, erstellt JEP 358 den Teil des Quellcodes neu, der die Nullreferenz auf den Operandenstapel verschoben hat.

3.2. Technische Aspekte

Nun , da wir ein gutes Verständnis davon, wie zu identifizieren null Referenzen Hilfreiche mit Nullpointer s, sie sich einigen technischen Aspekten davon einen Blick darauf werfen.

Zum einen wird eine detaillierte Meldung Berechnung nur dann , wenn die JVM selbst ein wirft Nullpointer - die Berechnung nicht ausgeführt werden , wenn wir ausdrücklich auf die Ausnahme werfen in unserem Java - Code. Der Grund dafür ist, dass wir in diesen Situationen höchstwahrscheinlich bereits eine aussagekräftige Nachricht im Ausnahmekonstruktor übergeben.

Zweitens berechnet JEP 358 die Nachricht träge, dh nur, wenn wir die Ausnahmemeldung drucken und nicht, wenn die Ausnahme auftritt . Infolgedessen sollte es für die üblichen JVM-Flows, bei denen wir Ausnahmen abfangen und erneut auslösen, keine Auswirkungen auf die Leistung geben, da die Ausnahmemeldung nicht immer gedruckt wird.

Schließlich kann die detaillierte Ausnahmemeldung lokale Variablennamen aus unserem Quellcode enthalten . Daher könnten wir dies als potenzielles Sicherheitsrisiko betrachten. Dies geschieht jedoch nur, wenn wir Code ausführen, der mit aktiviertem Flag -g kompiliert wurde , wodurch Debug-Informationen generiert und in unsere Klassendatei eingefügt werden.

Stellen Sie sich ein einfaches Beispiel vor, das wir zusammengestellt haben, um diese zusätzlichen Debug-Informationen aufzunehmen:

Employee employee = null; employee.getName();

Wenn wir diesen Code ausführen, gibt die Ausnahmemeldung den lokalen Variablennamen aus:

Cannot invoke "com.baeldung.java14.npe.HelpfulNullPointerException$Employee.getName()" because "employee" is null

Im Gegensatz dazu bietet die JVM ohne zusätzliche Debug-Informationen nur das, was sie über die Variable in der detaillierten Nachricht weiß:

Cannot invoke "com.baeldung.java14.npe.HelpfulNullPointerException$Employee.getName()" because "" is null

Anstelle des lokalen Variablennamens ( Mitarbeiter ) druckt die JVM den vom Compiler zugewiesenen Variablenindex .

4. Fazit

In diesem kurzen Tutorial haben wir uns mit hilfreichen NullPointerException s in Java 14 vertraut gemacht . Wie oben gezeigt, helfen uns verbesserte Nachrichten dabei, Code aufgrund der in den Ausnahmemeldungen enthaltenen Quellcodedetails schneller zu debuggen.

Wie immer ist der vollständige Quellcode des Artikels auf GitHub verfügbar.