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

java中的空指針異常情況以及解決方案

 更新時(shí)間:2021年10月01日 09:32:49   作者:程序猿新手_曹先生  
這篇文章主要介紹了java中的空指針異常情況以及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

概述

出現(xiàn)空指針異常,常常是因?yàn)槲覀冋{(diào)用的對(duì)象是空的而拋出的異常。

問題描述

第一種

out.println(request.getParameter("username")); 

如果request里面并沒有username的值,這時(shí)無法對(duì)空對(duì)象進(jìn)行操作的,就會(huì)拋出異常。

第二種

String userName = request.getParameter("username"); 
  If (userName.equals("root")) 
  {....} 

如果沒有username值,或者username為null時(shí),是不能將一個(gè)為null的對(duì)象與另外一個(gè)對(duì)象進(jìn)行比較的。

If ("root".equals(user Name)) 
  {....}

如果返回值與常量進(jìn)行比較時(shí),就可以避免調(diào)用null對(duì)象的equals方法。不會(huì)拋出異常。

第三種

假設(shè)有一個(gè)student類,有屬性name。

Student a;
String b = a.name;

這個(gè)時(shí)候就會(huì)報(bào)錯(cuò),因?yàn)閍為空的,解決辦法就是讓a指向一個(gè)對(duì)象,Student a = new Student();

問題定位

對(duì)于日志中的報(bào)錯(cuò)信息,在java中拋出異常是從內(nèi)往外,因此只需要重點(diǎn)關(guān)注第一行報(bào)錯(cuò)信息,下面的報(bào)錯(cuò)都是由于一層層傳遞調(diào)用該方法導(dǎo)致。

Java空指針異常的若干解決方案

Java中任何對(duì)象都可以為空,我們可以使用若干種方法來避免產(chǎn)生這類異常。比如我們傳統(tǒng)的空值檢測(cè),編程規(guī)范,以及使用java中各種工具類。

(1)最常用的一種就是直接對(duì) 對(duì)象進(jìn)行判斷

比如if(Object == null)來對(duì)所有用到的對(duì)象進(jìn)行判斷,這個(gè)對(duì)象也就是我們常用的函數(shù)參數(shù),返回值,以及類實(shí)例的成員變量等。當(dāng)我們檢測(cè)到null值時(shí),我們可以異常的類型拋出更具有針對(duì)性的異常類型,再附加上我們自己加的消息內(nèi)容。我們也可以直接使用一些庫函數(shù)來簡化代碼:

Object checkData = Object.requireNoNull(resultMessage,"The resultMessage must not be null")

如果我們使用過Lombok工具的話,里面有一個(gè)@NotNull注解,就是指被注釋的元素不能為空,就會(huì)自定檢測(cè)。

(2)第二種方法就是遵守編程規(guī)范,可以減少一定的空指針異常的發(fā)生。

Strings.isNullOrEmpty(str);
CollectionUtils.isEmpty(collection);
StringUtils.isEmpty(str);

if(object != null) {
    object.toString();)
} // 使用toString()這種方法的話,如果object為空的話,就會(huì)拋出異常
 String.valueOf(object) //將Object轉(zhuǎn)換為字符串,不管是否為null,不會(huì)拋出異常

如果返回是集合類型。而且是空的,不要返回null值,而是要返回一個(gè)空的集合,如果返回類型是對(duì)象的話,我們可以拋出異常。

public class Example {
     private static List<Integer> numbers = null; 
     public static List<Integer> getList() {
          if (numbers == null)
               return Collections.emptyList();
          else
               return numbers;
     }
}

檢查一個(gè)方法的參數(shù),在執(zhí)行方法之前,確保檢查了參數(shù)是否null,當(dāng)參數(shù)被適當(dāng)檢查后,方法會(huì)繼續(xù)執(zhí)行。否則拋出叫做llegalArgumentException的異常,并通知調(diào)用的方法傳入的參數(shù)有誤。

使用三元運(yùn)算符,可以避免NullPointerException,形式如下:

boolean expression ? value1:value2;

存在NullPointerException的安全方法

第一種使用instanceof 操作符

即使對(duì)象的引用為null,instanceOf操作符可使用。當(dāng)引用為null時(shí),instanceof操作符返回false,而且不會(huì)拋出NullPointerException,比如:

String str = null;
if(str instanceof null) {
    log.error(.......)
}

如何避免

確保所有對(duì)象在使用之前被初始化。

java空指針異常:java.lang.NullPointException

一.什么是java空指針異常

我們都知道java是沒有指針的,這里說的"java指針"指的就是java的引用,我們不在這里討論叫指針究竟合不合適,而只是針對(duì)這個(gè)異常本身進(jìn)行分析。

空指針就是空引用,java空指針異常就是引用本身為空,卻調(diào)用了方法,這個(gè)時(shí)候就會(huì)出現(xiàn)空指針異常。

可以理解,成員變量和方法是屬于對(duì)象的(除去靜態(tài)),在對(duì)象中才存在相對(duì)應(yīng)的成員變量和方法,然后通過對(duì)象去調(diào)用這些成員變量和方法。

對(duì)于空指針來說,它不指向任何對(duì)象,也就沒有所謂的成員變量和方法,這個(gè)時(shí)候用它去調(diào)用某些屬性和方法,當(dāng)然會(huì)出現(xiàn)空指針異常。

public class Test {
    private int a=1;
    private int b=2;
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Test t1 = new Test();
        Test t2 = null;
        System.out.println(t1.a);
        System.out.println(t2.a);
        System.out.println(t2.c());
    }
    public String c(){
        return "123";
    }
}

我們分析上面這段示例代碼,在Test類中,有兩個(gè)成員變量a和b,和一個(gè)方法c()。

然后在main()方法中,我們創(chuàng)建了兩個(gè)對(duì)象t1和t2,其中t1指向通過構(gòu)造方法實(shí)例出的Test對(duì)象,而t2只是聲明,并指向了空,并沒有指向?qū)嶋H的對(duì)象。

調(diào)試的時(shí)候,第一條輸出語句是可以通過編譯的,而執(zhí)行到第二條輸出語句的時(shí)候,由于空指針調(diào)用了不屬于它的a,程序終止,報(bào)告空指針異常。

同樣,注釋第二條輸出語句,程序在執(zhí)行到第三條輸出語句的時(shí)候,由于調(diào)用了不屬于它的c()方法,會(huì)出現(xiàn)一樣的錯(cuò)誤。

二.如何解決

對(duì)于每一個(gè)java程序員來說,幾乎都避免不了遇到空指針異常,特別是經(jīng)驗(yàn)不足的初學(xué)者。而且由于它的調(diào)試和查找相對(duì)其它異常來說比較困難,常常需要花費(fèi)很大的精力去解決它。

首先認(rèn)識(shí)一下java中的null

null是Java中一個(gè)很重要的概念。null設(shè)計(jì)初衷是為了表示一些缺失的東西,例如缺失的用戶、資源或其他東西。但是,一年后,令人頭疼的空指針異常給Java程序員帶來不少的騷擾。

null是java中的關(guān)鍵字,因此,它不能寫成NULL,Null,只能是null。

null是所有引用類型的默認(rèn)值,如果沒有讓一個(gè)引用指向一個(gè)實(shí)際存在的對(duì)象,它的默認(rèn)值就是null。null本質(zhì)上是一個(gè)值,這跟int的默認(rèn)值是0,boolean的默認(rèn)值是false一樣。現(xiàn)在,我們通常都使用像eclipse等的集成開發(fā)環(huán)境進(jìn)行開發(fā),一般在定義變量的時(shí)候都會(huì)進(jìn)行初始化(這也是寫代碼的一個(gè)良好的習(xí)慣),如果沒有進(jìn)行初始化,系統(tǒng)會(huì)進(jìn)行提示。

報(bào)空指針異常的原因有以下幾種:

  • 1字符串變量未初始化;
  • 2接口類型的對(duì)象沒有用具體的類初始化,比如:
    • List it;會(huì)報(bào)錯(cuò)
    • List it = new ArrayList();則不會(huì)報(bào)錯(cuò)了
  • 3當(dāng)一個(gè)對(duì)象的值為空時(shí),你沒有判斷為空的情況。你可以試著把下面的代碼前加一行代碼:
    • if(rb!=null && rb!="")
    • 改成:
    • if(rb==null);
    • if(rb!==null&&rb!="") 或者if("").equals(rb))

空指針的解決辦法:

重點(diǎn)關(guān)注報(bào)錯(cuò)發(fā)生的所在行,通過空指針異常產(chǎn)生的兩條主要原因診斷具體的錯(cuò)誤。同時(shí)為了避免空指針的發(fā)生,最好在做判斷處理時(shí)將“null”或者空值放于 設(shè)定的值之前。

常見空指針異常的簡要分析:

(1)空指針錯(cuò)誤

Java中的8種基本數(shù)據(jù)類型,變量的值可以有其默認(rèn)值,加入沒有對(duì)其正常賦值,java虛擬機(jī)是不能 正確編譯通過的,因此使用基本的Java數(shù)據(jù)類型一般是不會(huì)引起空指針異常的。實(shí)際開發(fā)中,大多數(shù)的空指針異常主要與對(duì)象的操作相關(guān)。

下面列出可能發(fā)生空指針異常的幾種情況及相應(yīng)解決方案:

代碼段1:

out.println(request.getParameter("username")); 

分析:代碼段1的功能十分簡單,就是輸出用戶輸入"username"的值。

說明:看上去,上面的語句找不出什么語法錯(cuò)誤,而且在大多數(shù)情況下也遇不到什么問題。但是,如果某個(gè)用戶在輸入數(shù)據(jù)時(shí)并沒有提供表單 域"username" 的值,或通過某種途徑繞過表單直接輸入時(shí),此request.getParameter("username")的值為空(注意不是空字符串,是空對(duì)象 null。),out對(duì)象的println方法是無法直接對(duì)空對(duì)象操作的,因此代碼段1所在的JSP頁面將會(huì)拋出 "Java.lang.NullPointerException"異常。而且即使對(duì)象可能為空時(shí),也調(diào)用Java.lang.Object或 Object對(duì)象本身的一些方法如toString(), equal(Object obj)等操作。

代碼段2:

String userName = request.getParameter("username"); 
If (userName.equals("root")) 
{....} 

分析:代碼段2的功能是檢測(cè)用戶提供的用戶名,如果是用戶名稱為"root"的用戶時(shí),就執(zhí)行一些特別的操作。

說明:在代碼段2中,如果有用戶沒有提供表單域"username"的值時(shí),字符串對(duì)象userName為null值,不能夠?qū)⒁粋€(gè)null的對(duì)象與另一 個(gè)對(duì)象直接比較,同樣,代碼段2所在的JSP頁面就會(huì)拋空指針錯(cuò)誤。

一個(gè)小技巧:如果要把某個(gè)方法的返回值與常量做比較,把常量放在前面,可以避免調(diào)用null對(duì)象的equals方法。譬如:

    If ("root".equals(userName)) 
  {....}

即使userName對(duì)象返回了null對(duì)象,這里也不會(huì)有空指針異常,可以照常運(yùn)轉(zhuǎn)。

代碼段3:

String userName = session.getAttribute("session.username").toString(); 

分析:代碼段3的功能是將session中session.username的值取出,并將該值賦給字符串對(duì)象userName。

說明:在一般情況下,如果在用戶已經(jīng)進(jìn)行某個(gè)會(huì)話,則不會(huì)出現(xiàn)什么問題;但是,如果此時(shí)應(yīng)用服務(wù)器重新啟動(dòng),而用戶還沒有重新登錄,(也可能是用戶關(guān)閉瀏 覽器,但是仍打開原來的頁面。)那么,此時(shí)該session的值就會(huì)失效,同時(shí)導(dǎo)致session中的session.username的值為空。對(duì)一個(gè) 為 null的對(duì)象的直接執(zhí)行toString()操作,就會(huì)導(dǎo)致系統(tǒng)拋出空指針異常。

代碼段4:

public static void main(String args[]){
       Person p=null;
       p.setName("張三");
       System.out.println(p.getName());
}

分析:聲明一個(gè)Person對(duì)象,并打印出該對(duì)象的中的Name名字。

說明:這個(gè)時(shí)候你的p就出現(xiàn)空指針異常,因?yàn)槟阒皇锹暶髁诉@個(gè)Person類型的對(duì)象并沒有創(chuàng)建對(duì)象,所以它的堆里面沒有地址引用,切忌你要用對(duì) 象掉用方法的時(shí)候一定要?jiǎng)?chuàng)建對(duì)象。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • mybatis中的異常BindingException詳解

    mybatis中的異常BindingException詳解

    這篇文章主要介紹了mybatis中的異常BindingException詳解,此異常是mybatis中拋出的,意思是使用的這個(gè)方法找到,但是因?yàn)閙apperScan()已經(jīng)掃描到了Mapper類了,在綁定Mapper.xml時(shí)沒有綁定到導(dǎo)致的,需要的朋友可以參考下
    2024-01-01
  • 詳解MyBatis?ResultSetHandler?結(jié)果集的解析過程

    詳解MyBatis?ResultSetHandler?結(jié)果集的解析過程

    這篇文章主要為大家介紹了MyBatis?ResultSetHandler?結(jié)果集的解析過程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • Java靜態(tài)方法不具有多態(tài)性詳解

    Java靜態(tài)方法不具有多態(tài)性詳解

    下面小編就為大家?guī)硪黄狫ava靜態(tài)方法不具有多態(tài)性詳解。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-06-06
  • mybatisplus之Wrappers.ne踩坑記錄解決

    mybatisplus之Wrappers.ne踩坑記錄解決

    這篇文章主要為大家介紹了mybatisplus之Wrappers.ne踩坑記錄解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05
  • Java 中通過 key 獲取鎖的方法

    Java 中通過 key 獲取鎖的方法

    這篇文章主要介紹了Java 中通過 key 獲取鎖,本文演示如何對(duì)某個(gè) key 加鎖,以保證對(duì)該 key 的并發(fā)操作限制,可以實(shí)現(xiàn)同一個(gè) key 一個(gè)或者多個(gè)線程同時(shí)執(zhí)行,需要的朋友可以參考下
    2022-11-11
  • java中拼接字符串的5種方法效率對(duì)比

    java中拼接字符串的5種方法效率對(duì)比

    這篇文章主要給大家介紹了關(guān)于java中拼接字符串的5種方法效率對(duì)比的相關(guān)資料,文中通過示例代碼和圖片介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-01-01
  • 對(duì)java for 循環(huán)執(zhí)行順序的詳解

    對(duì)java for 循環(huán)執(zhí)行順序的詳解

    今天小編就為大家分享一篇對(duì)java for 循環(huán)執(zhí)行順序的詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-06-06
  • Maven中Could not find artifact XXXX的錯(cuò)誤解決

    Maven中Could not find artifact XXXX的錯(cuò)誤解決

    本文主要介紹了Maven中Could not find artifact XXXX的錯(cuò)誤解決,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Java?easyexcel使用教程之導(dǎo)出篇

    Java?easyexcel使用教程之導(dǎo)出篇

    EasyExcel是阿里巴巴開源的一個(gè)excel處理框架,以使用簡單,節(jié)省內(nèi)存著稱,下面這篇文章主要給大家介紹了關(guān)于Java?easyexcel使用教程之導(dǎo)出篇的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06
  • java通過AES生成公鑰加密數(shù)據(jù)ECC加密公鑰

    java通過AES生成公鑰加密數(shù)據(jù)ECC加密公鑰

    這篇文章主要為大家介紹了java通過AES生成公鑰加密數(shù)據(jù)ECC加密公鑰實(shí)現(xiàn)案例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12

最新評(píng)論