Haben Sie java.lang.NullPointerException (NPE) bemerkt? 8 Best Practices zur Vermeidung von Laufzeit-NPE in Java
Veröffentlicht: 2020-10-07
Vermeidung von Null-Zeiger-Ausnahmen in Java und Java-Tipps und Best Practices zur Vermeidung von Null-Zeiger-Ausnahmen in Java.
Ich bin mir sicher, dass Sie als Java-Entwickler ab dem ersten Tag mit Null Pointer Exception (NPE) konfrontiert waren. In den meisten Fällen zeigt die NPE-Ausnahme einen klaren Stack-Trace, der die Grundursache derselben festlegt, aber im Falle einer großen Anwendung auf Unternehmensebene, in der Sie Hunderte von Klassen haben, wird es zum Albtraum, die wahre Grundursache herauszufinden.
Was ist eine Null-Zeiger-Ausnahme (NPE)?
NullPointerException (NPE)
ist eine Ausnahme, die auftritt, wenn Sie versuchen, einen Verweis zu verwenden, der auf keinen Speicherort (Null) zeigt, als würde er auf ein Objekt verweisen.
Das Aufrufen einer Methode für eine null
oder der Versuch, auf ein Feld einer Nullreferenz zuzugreifen, löst eine NPE aus. Dies ist die häufigste Ursache.
Gemäß JavaDoc sind im Folgenden die Hauptursachen für NPE aufgeführt:
- Wirft
null
, als wäre es einThrowable
Wert. - Aufrufen der Instanzmethode eines
null
. - Zugreifen auf oder Ändern des Felds eines
null
. - Nimmt die Länge von
null
, als wäre es ein Array. - Zugreifen auf oder Ändern der Slots von
null
, als wäre es ein Array.
Jetzt ist die eigentliche Frage, wie man java.lang.NullPointerException zur Laufzeit vermeidet? In diesem Tutorial sehen wir uns einige Beispiele an, die NPE zur Laufzeit erstellen, und Schritte, die wir ausführen müssen, um dies zu beheben.
Lassen Sie uns zuerst NPE zur Laufzeit erstellen. Sehen Sie sich das folgende Beispiel CrunchifyNullPointerExceptionTips.java
an
Wir werden NPE auf 3 verschiedene Arten erstellen
- NPE wird ausgelöst, wenn Sie versuchen, auf ein Nullobjekt zuzugreifen
- NPE wird ausgelöst, wenn Sie versuchen, einen Null-String zu konvertieren
- NPE wird ausgelöst, wenn Sie versuchen, während der Klasseninitialisierung auf null Object zuzugreifen
Erstellen Sie die Klasse CrunchifyNullPointerExceptionTips.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
package crunchify . com . tutorial ; /** * @author Crunchify.com * Have you Noticed java.lang.NullPointerException (NPE)? 8 Best practices to avoid runtime NPE in Java */ public class CrunchifyNullPointerExceptionTips { public static void main ( String [ ] args ) { try { // Example 1: NPE will be thrown if you are trying to access null Object CrunchifyNPE1 ( ) ; } catch ( NullPointerException crunchifyNPE1 ) { System . out . println ( "Exception in CrunchifyNPE1()" ) ; crunchifyNPE1 . printStackTrace ( ) ; } try { // Example 2: NPE will be thrown if you are trying to convert null String CrunchifyNPE2 ( ) ; } catch ( NullPointerException crunchifyNPE2 ) { System . out . println ( "\nException in CrunchifyNPE2()" ) ; // printStackTrace(): Prints this throwable and its backtrace to the standard error stream. // This method prints a stack trace for this Throwable object on the error output stream that is the value of the field System.err. // The first line of output contains the result of the toString() method for this object. // Remaining lines represent data previously recorded by the method fillInStackTrace(). crunchifyNPE2 . printStackTrace ( ) ; } try { // Example 3: NPE will be thrown if you are trying to access null Object during Class Initialization CrunchifyNPETest npe = new CrunchifyNPETest ( ) ; npe . getName ( ) ; // NullPointerException: Thrown when an application attempts to use null in a case where an object is required. These include: // - Calling the instance method of a null object. // - Accessing or modifying the field of a null object. // - Taking the length of null as if it were an array. // - Accessing or modifying the slots of null as if it were an array. // - Throwing null as if it were a Throwable value. } catch ( NullPointerException crunchifyNPE3 ) { System . out . println ( "\n Exception in CrunchifyNPETest()" ) ; crunchifyNPE3 . printStackTrace ( ) ; } } private static void CrunchifyNPE1 ( ) { Object crunchifyObj = null ; // hasCode(): Returns a hash code value for the object. // This method is supported for the benefit of hash tables such as those provided by java.util.HashMap. crunchifyObj . hashCode ( ) ; } private static void CrunchifyNPE2 ( ) { String crunchifyString ; crunchifyString = "https://crunchify.com" ; // The line 40 declares a variable named "crunchifyString", but, it does not contain a primitive value. Instead it contains a pointer (because the type is String // which is a reference type). Since you did not say as yet what to point to Java sets it to null, meaning "I am pointing at nothing". // In line 41, the new keyword is used to instantiate (or create) an object of type String and the pointer variable "crunchifyString" is assigned this // object. You can now reference the object using the dereferencing operator . (a dot). System . out . println ( "\nvalue: " + crunchifyString . toString ( ) + ", length: " + crunchifyString . length ( ) ) ; System . out . println ( "No NPE exception on line 51" ) ; // Now Let's create NPE String crunchifyString2 = null ; System . out . println ( crunchifyString2 . toString ( ) ) ; } } class CrunchifyNPETest { private String crunchifyName ; public void setName ( String name ) { this . crunchifyName = name ; } public void getName ( ) { printName ( crunchifyName ) ; } private void printName ( String s ) { System . out . println ( s + " (" + s . length ( ) + ")" ) ; } } |
Ergebnis:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
Exception in CrunchifyNPE1 ( ) java . lang . NullPointerException : Cannot invoke "Object.hashCode()" because "crunchifyObj" is null at crunchify . com . tutorial . CrunchifyNullPointerExceptionTips . CrunchifyNPE1 ( CrunchifyNullPointerExceptionTips . java : 59 ) at crunchify . com . tutorial . CrunchifyNullPointerExceptionTips . main ( CrunchifyNullPointerExceptionTips . java : 14 ) value : https : //crunchify.com, length: 21 No NPE exception on line 51 Exception in CrunchifyNPE2 ( ) Exception in CrunchifyNPETest ( ) java . lang . NullPointerException : Cannot invoke "String.toString()" because "crunchifyString2" is null at crunchify . com . tutorial . CrunchifyNullPointerExceptionTips . CrunchifyNPE2 ( CrunchifyNullPointerExceptionTips . java : 75 ) at crunchify . com . tutorial . CrunchifyNullPointerExceptionTips . main ( CrunchifyNullPointerExceptionTips . java : 23 ) java . lang . NullPointerException : Cannot invoke "String.length()" because "s" is null at crunchify . com . tutorial . CrunchifyNPETest . printName ( CrunchifyNullPointerExceptionTips . java : 92 ) at crunchify . com . tutorial . CrunchifyNPETest . getName ( CrunchifyNullPointerExceptionTips . java : 88 ) at crunchify . com . tutorial . CrunchifyNullPointerExceptionTips . main ( CrunchifyNullPointerExceptionTips . java : 38 ) Process finished with exit code 0 |
Nun, es gibt einige Tipps und Tricks, mit denen wir NullPointerException zur Laufzeit vermeiden können. Lass uns einen Blick darauf werfen.

Tipp 1:
Eclipse/IntelliJ IDE versucht, NPE im Arbeitsbereich anzuzeigen. Korrigieren Sie Ihren Code nur während der Entwicklung.

Tipp 2:
Fügen Sie crunchifyI
sNullorEmpty
()
-Prüfung vor einer Operation für ein Objekt hinzu. Fügen Sie dies zu CrunchifyNullPointerExceptionTips.java
1 2 3 4 5 6 7 8 |
public static boolean crunchifyIsNullOrEmpty ( String crunchifyStr ) { if ( crunchifyStr == null ) return true ; else if ( crunchifyStr . trim ( ) . equals ( "" ) ) return true ; else return false ; } |
Im obigen Java-Programm werden die Zeilen 55 und 56 dadurch ersetzt.
1 2 3 4 5 6 |
String crunchifyString2 = null ; if ( ! crunchifyIsNullOrEmpty ( crunchifyString2 ) ) { System . out . println ( crunchifyString2 . toString ( ) ) ; } else { System . out . println ( "crunchifyString2 is null" ) ; } |
Tipp 3:
Prüfen Sie, ob String nach der Operation trim() null
oder leer ist.
1 2 3 |
public static boolean isNullOrEmptyAfterTrim ( String crunchifyStr ) { return ( crunchifyStr == null | | crunchifyStr . trim ( ) . length ( ) == 0 ) ; } |
Tipp 4:
Verwenden Sie immer den Try Catch block
, um einen ununterbrochenen Runtime-Prozess zu verhindern.
1 2 3 4 5 |
try { CrunchifyNPE1 ( ) ; } catch ( NullPointerException npe ) { System . out . println ( "Exception in CrunchifyNPE1()" + npe ) ; } |
Tipp 5:
Collections.emptyList()
wird aufgrund der besseren Handhabung von Generika bevorzugt.
Tipp 6:
Verwenden Sie Java Assertions
Eine Assertion ist eine Aussage, die es Ihnen ermöglicht, Ihre Annahmen über Ihren Code zu testen. Wenn Sie beispielsweise eine Methode schreiben, die den Namen im System zurückgibt, können Sie behaupten, dass der zurückgegebene otherName if String null ist.
Die grundlegende Verwendung von Behauptungen wäre:
1 2 3 4 5 6 7 8 |
assert < Expression > ; // or another usage is assert < Expression1 > : < Expression2 > ; // in our program add line below. private void printName ( String s ) { assert ( s ! = null ) : "Name must be not null" ; System . out . println ( s + " (" + s . length ( ) + ")" ) ; } |
Aber es gibt einen Haken: Assertion ist in der Produktionsumgebung nicht verfügbar und wir sollten Assertion nicht mit irgendeiner Geschäftslogik verwenden.
Tipp 7:
Versuchen Sie, containsKey()
, containsValue()
, contains()
Prüfungen zu verwenden.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
package com . crunchify . tutorial ; import java . util . * ; /** * @author Crunchify.com * */ public class CrunchifyContainsKeyExample { public static void main ( String args [ ] ) { HashMap < Integer , String > crunchifyMap = new HashMap < Integer , String > ( ) ; // populate hash map crunchifyMap . put ( 1 , "Crunchify" ) ; crunchifyMap . put ( 2 , "wordpress" ) ; crunchifyMap . put ( 3 , "java tutorials" ) ; // check existence of key 4 if ( crunchifyMap . containsKey ( 4 ) ) { System . out . println ( "Check if key 2 exists: " + crunchifyMap . get ( 4 ) ) ; } else { System . out . println ( "NPE for value 4 avoided" ) ; } } } |
Tipp 8:
Zusammenfassend ist es immer eine gute Praxis, sich während der Entwicklung um NPE zu kümmern, anstatt zur Laufzeit in der Produktion zu debuggen. Es gibt eine Reihe weiterer Tipps und Tricks, die Spring Framework Annotation, Factory Pattern
, Null Object Pattern usw. verwenden. Aber ich werde es jetzt kurz machen.
Wird wahrscheinlich in einer Woche ein neues Tutorial zu diesem Thema veröffentlichen. Bleib dran.
Möchten Sie etwas zu diesem Tutorial hinzufügen ODER ein Problem gefunden haben, melden Sie sich bitte und geben Sie Ihre Kommentare ab.