亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

什麼是 NullPointerException,如何修復(fù)它?
P粉649990273
P粉649990273 2023-08-23 10:22:08
0
2
798
<p>什麼是空指標(biāo)例外 (<code>java.lang.NullPointerException</code>) 以及導(dǎo)致它們的原因是什麼? </p> <p>可以使用哪些方法/工具來決定原因,以便阻止異常導(dǎo)致程式提前終止? </p>
P粉649990273
P粉649990273

全部回覆(2)
P粉252116587

NullPointerException 是當(dāng)您嘗試使用指向記憶體中任何位置 (null) 的參考時(shí)發(fā)生的異常,就像引用物件一樣。對(duì)空引用呼叫方法或嘗試存取空引用的欄位將觸發(fā) NullPointerException。這些是最常見的,但 中列出了其他方法NullPointerException# javadoc 頁面。

我能想到的用來說明 NullPointerException 的最快範(fàn)例程式碼可能是:

public class Example {

    public static void main(String[] args) {
        Object obj = null;
        obj.hashCode();
    }

}

main 內(nèi)的第一行,我明確地將 Object 引用 obj 設(shè)為 null 。這意味著我有一個(gè)引用,但它沒有指向任何物件。之後,我嘗試透過呼叫該引用的方法來將該引用視為指向一個(gè)物件。這會(huì)導(dǎo)致 NullPointerException,因?yàn)樵谝弥赶虻奈恢脹]有要執(zhí)行的程式碼。

(這是一個(gè)技術(shù)問題,但我認(rèn)為值得一提的是:指向null 的引用與指向無效記憶體位置的C 指標(biāo)不同??罩笜?biāo)實(shí)際上不指向任何地方,這與指向一個(gè)恰好無效的位置有細(xì)微的不同。)

P粉593536104

Java 中有兩種主要類型的變數(shù):

  1. 基元:包含資料的變數(shù)。如果您想操作原始變數(shù)中的數(shù)據(jù),您可以直接操作該變數(shù)。按照慣例,原始類型以小寫字母開頭。例如,intchar 類型的變數(shù)是基元。

  2. 引用:包含物件記憶體位址的變量,即引用物件的變數(shù)程式碼>.如果您想要操作引用變數(shù)引用的Object,則必須取消引用它。取消引用通常需要使用 . 存取方法或字段,或使用 [ 索引數(shù)組。按照慣例,引用類型通常用以大寫字母開頭的類型來表示。例如,Object 類型的變數(shù)是引用。

考慮以下程式碼,您在其中聲明 int 類型的原始變量,但不初始化它:

int x;
int y = x + x;

這兩行會(huì)使程式崩潰,因?yàn)闆]有為 x 指定任何值,而我們正在嘗試使用 x 的值來指定 y >。所有基元在被操作之前都必須初始化為可用值。

現(xiàn)在事情變得有趣了。 引用變數(shù)可以設(shè)定為null,這表示「我沒有引用任何東西」。如果您以這種方式明確設(shè)定引用變量,則可以在引用變數(shù)中取得null 值,或引用變數(shù)未初始化且編譯器不會(huì)擷取它(Java 會(huì)自動(dòng)將該變數(shù)設(shè)為null )。

如果您明確或透過 Java 自動(dòng)將參考變數(shù)設(shè)為 null,並且您嘗試取消引用它,您將得到一個(gè) NullPointerException。

當(dāng)您宣告一個(gè)變數(shù)但在嘗試使用該變數(shù)的內(nèi)容之前沒有建立物件並將其指派給該變數(shù)時(shí),通常會(huì)發(fā)生NullPointerException (NPE)。所以你引用了一些實(shí)際上並不存在的東西。

採用以下程式碼:

Integer num;
num = new Integer(10);

第一行宣告了一個(gè)名為num的變量,但它實(shí)際上還不包含引用值。由於您還沒有說出要指向什麼,Java 將其設(shè)為 null

第二行,new關(guān)鍵字用於實(shí)例化(或建立)一個(gè)Integer類型的對(duì)象,引用變數(shù)num 被指派給該Integer 物件。

如果您在建立物件之前嘗試取消參考num,,您將得到一個(gè)NullPointerException。在最簡(jiǎn)單的情況下,編譯器會(huì)捕獲問題並讓您知道“num 可能尚未初始化”,但有時(shí)您可能會(huì)編寫不直接建立物件的程式碼。

例如,您可能有以下方法:

public void doSomething(SomeObject obj) {
   // Do something to obj, assumes obj is not null
   obj.myMethod();
}

在這種情況下,您不會(huì)建立物件 obj,而是假設(shè)它是在呼叫 doSomething() 方法之前建立的。請(qǐng)注意,可以像這樣呼叫該方法:

doSomething(null);

在這種情況下,objnull,並且語句obj.myMethod() 會(huì)拋出NullPointerException >.

如果該方法打算像上面的方法那樣對(duì)傳入的物件執(zhí)行某些操作,則拋出NullPointerException 是適當(dāng)?shù)模驗(yàn)檫@是程式設(shè)計(jì)師錯(cuò)誤,而程式設(shè)計(jì)師需要該資訊偵錯(cuò)目的。

除了由於方法邏輯引發(fā)的NullPointerException 例外之外,您還可以檢查方法參數(shù)中的null 值,並透過新增類似以下內(nèi)容來明確拋出NPE:在方法開頭附近跟隨:

// Throws an NPE with a custom error message if obj is null
Objects.requireNonNull(obj, "obj must not be null");

請(qǐng)注意,在錯(cuò)誤訊息中明確說明哪個(gè)物件不能為null會(huì)很有幫助。驗(yàn)證這一點(diǎn)的優(yōu)點(diǎn)是 1) 您可以返回自己更清晰的錯(cuò)誤訊息,2) 對(duì)於方法的其餘部分,您知道除非重新分配 obj ,否則它不為 null 並且可以安全地取消引用.

或者,在某些情況下,該方法的目的不僅僅是對(duì)傳入的物件進(jìn)行操作,因此空參數(shù)可能是可接受的。在這種情況下,您需要檢查空參數(shù)並採取不同的行為。您還應(yīng)該在文件中對(duì)此進(jìn)行解釋。例如,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
    }
}

最後,如何使用堆疊追蹤來找出異常和原因

#

具有查找錯(cuò)誤功能的聲納可以偵測(cè) NPE。 sonar能否動(dòng)態(tài)擷取JVM所造成的空指標(biāo)例外一個(gè)>

現(xiàn)在 Java 14 新增了一項(xiàng)新的語言功能來顯示 NullPointerException 的根本原因。自 2006 年以來,此語言功能已成為 SAP 商業(yè) JVM 的一部分。

在 Java 14 中,以下是 NullPointerException 例外訊息範(fàn)例:

導(dǎo)致 NullPointerException 發(fā)生的情況清單

以下是 Java 語言規(guī)範(fàn)直接*提到的發(fā)生 NullPointerException 的所有情況:

  • 存?。慈〉没蛟O(shè)定)空引用的實(shí)例欄位。 (靜態(tài)字段不算!)
  • 呼叫空引用的實(shí)例方法。 (靜態(tài)方法不算?。?/li>
  • 拋出空值;
  • #存取空數(shù)組的元素。
  • 在 null 同步 - synchronized (someNullReference) { ... }
  • 如果其運(yùn)算元之一是裝箱空引用,則任何整數(shù)/浮點(diǎn)運(yùn)算子都可能拋出 NullPointerException
  • 如果裝箱值為 null,則拆箱轉(zhuǎn)換會(huì)引發(fā) NullPointerException。
  • 對(duì) null 引用呼叫 super 會(huì)引發(fā) NullPointerException。如果您感到困惑,這是在談?wù)摵细竦某悇e建構(gòu)函式呼叫:
class Outer {
    class Inner {}
}
class ChildOfInner extends Outer.Inner {
    ChildOfInner(Outer o) { 
        o.super(); // if o is null, NPE gets thrown
    }
}
  • 使用 for (element : iterable) 迴圈來循環(huán)遍歷空集合/陣列。

  • switch (foo) { ... }(無論是表達(dá)式或語句)在foo 時(shí)可以拋出NullPointerException#為空。

  • foo.new SomeInnerClass() 當(dāng) foo 為 null 時(shí)拋出 NullPointerException。

  • name1::name2primaryExpression::name# 形式的方法參考在下列情況下求值時(shí)會(huì)拋出NullPointerException name1 或primaryExpression 計(jì)算結(jié)果為null。

    來自JLS 的註解指出,someInstance.someStaticMethod() 不會(huì)拋出NPE,因?yàn)?code>someStaticMethod 是靜態(tài)的,但someInstance:: someStaticMethod 仍然拋出NPE!

* 請(qǐng)注意,JLS 可能也間接談?wù)摿撕芏嘤嘘P(guān) NPE 的內(nèi)容。

最新下載
更多>
網(wǎng)站特效
網(wǎng)站源碼
網(wǎng)站素材
前端模板