詳解Java中NullPointerException異常的原因詳解以及解決方法
NullPointerException是當您嘗試使用指向內存中空位置的引用(null)時發生的異常,就好像它引用了一個對象一樣。
當我們聲明引用變量(即對象)時,實際上是在創建指向對象的指針。考慮以下代碼,您可以在其中聲明基本類型的整型變量x:
int x;x = 10;
在此示例中,變量x是一個整型變量,Java將為您初始化為0。當您在第二行中將其分配給10時,值10將被寫入x指向的內存中。
但是,當您嘗試聲明引用類型時會發生不同的事情。請使用以下代碼:
Integer num;num = new Integer(10);
第一行聲明了一個名為的變量num,但它不包含原始值。相反,它包含一個指針(因為類型Integer是一個引用類型)。既然你還沒有說什么指向Java,它將它設置為null,意思是“ 我什么都沒有指向”。
在第二行中,new關鍵字用于實例化(或創建)Integer類型的對象,并為指針變量num分配此對象。您現在可以使用解引用運算符.(點)來引用對象。
在當你聲明了一個變量,但是沒有創建一個對象,會發生Exception。如果您在創建num對象之前嘗試取消引用,則會得到一個NullPointerException。在最瑣碎的情況下,編譯器將捕獲問題并讓您知道“num可能尚未初始化”,但有時您編寫的代碼不會直接創建對象。
例如,您可能使用了如下的方法:
public void doSomething(SomeObject obj) { //do something to obj}
在這種情況下,您沒有創建對象obj,而是假設它是在doSomething調用方法之前創建的。如果你像這樣調用方法:
doSomething(null);
在這種情況下obj為null。如果該方法旨在對傳入的對象執行某些操作,則需要拋出異常,因為NullPointerException它是程序錯誤,程序員將需要該信息用于調試的目的。
或者,可能存在這樣的情況:該方法的目的不僅僅是對傳入的對象進行操作,因此可以接受空參數。在這種情況下,您需要檢查null參數并采取不同的行為。您還應該在文檔中解釋這一點。例如,doSomething應該最好寫成:
/** * @param obj An optional foo for ____. May be null, in which case * the result will be ____. */public void doSomething(SomeObject obj) { if(obj != null) { //do something } else { //do something else }}
我如何解決它?
所以你有一個NullPointerException。應該如何解決?讓我們舉一個簡單的例子,它拋出NullPointerException:
public class Printer { private String name; public void setName(String name) { this.name = name; } public void print() { printString(name); } private void printString(String s) { System.out.println(s + ' (' + s.length() + ')'); } public static void main(String[] args) { Printer printer = new Printer(); printer.print(); }}
標識空值
第一步是確切地確定導致異常的值。為此,我們需要做一些調試。學習閱讀堆棧跟蹤很重要。這將顯示拋出異常的位置:
Exception in thread 'main' java.lang.NullPointerException at Printer.printString(Printer.java:13) at Printer.print(Printer.java:9) at Printer.main(Printer.java:19)
在這里,我們看到在第13行拋出異常(在printString方法中)。查看該行并通過添加日志記錄語句或使用調試器來檢查哪些值為空。我們發現它s是null,并且調用length方法會拋出異常。我們可以看到程序在s.length()方法中刪除時停止拋出異常。
追蹤這些值來自哪里
接下來檢查此值的來源。按照該方法的調用者,我們可以看到,s與傳遞printString(name)的print()方法,并this.name為空。
跟蹤應設置這些值的位置
在哪里this.name設置?在setName(String)方法中。通過一些更多的調試,我們可以看到根本沒有調用此方法。如果調用該方法,請確保檢查調用這些方法的順序,并且在print方法之后不調用set 方法。
這足以為我們提供一個解決方案:在調用printer.setName()之前添加調用printer.print()。
其他修正
該變量可以具有默認值(并且setName可以防止將其設置為null):
private String name = '';
任一print或printString方法可以檢查空,例如:
printString((name == null) ? '' : name);
或者您可以設計如下所示的類,以便name 始終具有非null值:
public class Printer { private final String name; public Printer(String name) { this.name = Objects.requireNonNull(name); } public void print() { printString(name); } private void printString(String s) { System.out.println(s + ' (' + s.length() + ')'); } public static void main(String[] args) { Printer printer = new Printer('123'); printer.print(); }}
到此這篇關于詳解Java中NullPointerException異常的原因詳解以及解決方法的文章就介紹到這了,更多相關Java NullPointerException異常內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!
相關文章:
