欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解Java中NullPointerException異常的原因詳解以及解決方法

 更新時(shí)間:2020年08月06日 11:01:01   作者:Allen Chou  
這篇文章主要介紹了詳解Java中NullPointerException異常的原因詳解以及解決方法。文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

NullPointerException是當(dāng)您嘗試使用指向內(nèi)存中空位置的引用(null)時(shí)發(fā)生的異常,就好像它引用了一個對象一樣。

當(dāng)我們聲明引用變量(即對象)時(shí),實(shí)際上是在創(chuàng)建指向?qū)ο蟮闹羔???紤]以下代碼,您可以在其中聲明基本類型的整型變量x:

int x;
x = 10;

在此示例中,變量x是一個整型變量,Java將為您初始化為0。當(dāng)您在第二行中將其分配給10時(shí),值10將被寫入x指向的內(nèi)存中。

但是,當(dāng)您嘗試聲明引用類型時(shí)會發(fā)生不同的事情。請使用以下代碼:

Integer num;
num = new Integer(10);

第一行聲明了一個名為的變量num,但它不包含原始值。相反,它包含一個指針(因?yàn)轭愋虸nteger是一個引用類型)。既然你還沒有說什么指向Java,它將它設(shè)置為null,意思是“ 我什么都沒有指向”。

在第二行中,new關(guān)鍵字用于實(shí)例化(或創(chuàng)建)Integer類型的對象,并為指針變量num分配此對象。您現(xiàn)在可以使用解引用運(yùn)算符.(點(diǎn))來引用對象。

在當(dāng)你聲明了一個變量,但是沒有創(chuàng)建一個對象,會發(fā)生Exception。如果您在創(chuàng)建num對象之前嘗試取消引用,則會得到一個NullPointerException。在最瑣碎的情況下,編譯器將捕獲問題并讓您知道“num可能尚未初始化”,但有時(shí)您編寫的代碼不會直接創(chuàng)建對象。

例如,您可能使用了如下的方法:

public void doSomething(SomeObject obj) {
  //do something to obj
}

在這種情況下,您沒有創(chuàng)建對象obj,而是假設(shè)它是在doSomething調(diào)用方法之前創(chuàng)建的。如果你像這樣調(diào)用方法:

doSomething(null);

在這種情況下obj為null。如果該方法旨在對傳入的對象執(zhí)行某些操作,則需要拋出異常,因?yàn)镹ullPointerException它是程序錯誤,程序員將需要該信息用于調(diào)試的目的。

或者,可能存在這樣的情況:該方法的目的不僅僅是對傳入的對象進(jìn)行操作,因此可以接受空參數(shù)。在這種情況下,您需要檢查null參數(shù)并采取不同的行為。您還應(yīng)該在文檔中解釋這一點(diǎn)。例如,doSomething應(yīng)該最好寫成:

/**
 * @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。應(yīng)該如何解決?讓我們舉一個簡單的例子,它拋出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();
  }
}

標(biāo)識空值

第一步是確切地確定導(dǎo)致異常的值。為此,我們需要做一些調(diào)試。學(xué)習(xí)閱讀堆棧跟蹤很重要。這將顯示拋出異常的位置:

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方法中)。查看該行并通過添加日志記錄語句或使用調(diào)試器來檢查哪些值為空。我們發(fā)現(xiàn)它s是null,并且調(diào)用length方法會拋出異常。我們可以看到程序在s.length()方法中刪除時(shí)停止拋出異常。

追蹤這些值來自哪里

接下來檢查此值的來源。按照該方法的調(diào)用者,我們可以看到,s與傳遞printString(name)的print()方法,并this.name為空。

跟蹤應(yīng)設(shè)置這些值的位置

在哪里this.name設(shè)置?在setName(String)方法中。通過一些更多的調(diào)試,我們可以看到根本沒有調(diào)用此方法。如果調(diào)用該方法,請確保檢查調(diào)用這些方法的順序,并且在print方法之后不調(diào)用set 方法。

這足以為我們提供一個解決方案:在調(diào)用printer.setName()之前添加調(diào)用printer.print()。

其他修正

該變量可以具有默認(rèn)值(并且setName可以防止將其設(shè)置為null):

private String name = "";

任一print或printString方法可以檢查空,例如:

printString((name == null) ? "" : name);

或者您可以設(shè)計(jì)如下所示的類,以便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();
  }
}

到此這篇關(guān)于詳解Java中NullPointerException異常的原因詳解以及解決方法的文章就介紹到這了,更多相關(guān)Java NullPointerException異常內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java垃圾回收器的方法和原理總結(jié)

    Java垃圾回收器的方法和原理總結(jié)

    本篇文章主要介紹了Java垃圾回收器的方法和原理總結(jié),Java垃圾回收器是Java虛擬機(jī)的重要模塊,具有一定的參考價(jià)值,有興趣的可以了解一下。
    2016-12-12
  • java 獲取服務(wù)器真實(shí)IP的實(shí)例

    java 獲取服務(wù)器真實(shí)IP的實(shí)例

    這篇文章主要介紹了java 獲取服務(wù)器真實(shí)IP的實(shí)例的相關(guān)資料,這里提供實(shí)現(xiàn)方法幫助大家學(xué)習(xí)理解這部分內(nèi)容,需要的朋友可以參考下
    2017-08-08
  • MyBatis-Plus流式查詢的實(shí)現(xiàn)示例

    MyBatis-Plus流式查詢的實(shí)現(xiàn)示例

    MyBatis-Plus 從 3.5.4 版本開始支持流式查詢,通過ResultHandler接口實(shí)現(xiàn)結(jié)果集的流式查詢,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-12-12
  • 詳解SpringBoot獲得Maven-pom中版本號和編譯時(shí)間戳

    詳解SpringBoot獲得Maven-pom中版本號和編譯時(shí)間戳

    這篇文章主要介紹了詳解SpringBoot獲得Maven-pom中版本號和編譯時(shí)間戳,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-01-01
  • SpringBoot實(shí)現(xiàn)Redis多數(shù)據(jù)庫切換(多數(shù)據(jù)源配置)

    SpringBoot實(shí)現(xiàn)Redis多數(shù)據(jù)庫切換(多數(shù)據(jù)源配置)

    在實(shí)際開發(fā)中,隨著業(yè)務(wù)復(fù)雜度提升,我們常常會遇到?Redis?需要按不同業(yè)務(wù)模塊分庫管理的需求,本文將以?Spring?Boot?為例,教大家如何優(yōu)雅地實(shí)現(xiàn)?Redis?多數(shù)據(jù)庫(多數(shù)據(jù)源)切換,需要的可以了解下
    2025-07-07
  • openGauss數(shù)據(jù)庫JDBC環(huán)境連接配置的詳細(xì)過程(Eclipse)

    openGauss數(shù)據(jù)庫JDBC環(huán)境連接配置的詳細(xì)過程(Eclipse)

    這篇文章主要介紹了openGauss數(shù)據(jù)庫JDBC環(huán)境連接配置(Eclipse),演示基于JDBC開發(fā)的主要步驟,會涉及創(chuàng)建數(shù)據(jù)庫、創(chuàng)建表、插入數(shù)據(jù)等,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06
  • 淺析java異常棧

    淺析java異常棧

    給大家通過一個簡單的代碼實(shí)例給大家分型了java異常棧問題,需要的朋友參考一下吧。
    2017-12-12
  • Java中的Fork/Join框架使用詳解

    Java中的Fork/Join框架使用詳解

    這篇文章主要介紹了Java中的Fork/Join框架使用詳解,Fork/Join?框架:就是在必要的情況下,將一個大任務(wù),進(jìn)行<BR>拆分(fork)成若干個小任務(wù)(拆到不可再拆時(shí)),再將一個個<BR>的小任務(wù)運(yùn)算的結(jié)果進(jìn)行?join?匯總,需要的朋友可以參考下
    2024-01-01
  • 深入理解 CAS 算法原理已經(jīng)在jdk中的運(yùn)用

    深入理解 CAS 算法原理已經(jīng)在jdk中的運(yùn)用

    這篇文章主要介紹了深入理解 CAS 算法原理已經(jīng)在jdk中的運(yùn)用,幫助大家更好的使用Java,感興趣的朋友可以了解下
    2020-12-12
  • SpringMVC請求流程源碼解析

    SpringMVC請求流程源碼解析

    這篇文章主要介紹了SpringMVC請求流程源碼分析,包括springmvc使用,SpringMVC啟動過程及SpringMVC請求過程,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-07-07

最新評論