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

Java中空指針異常該如何避免詳解

 更新時(shí)間:2022年03月28日 08:59:04   作者:學(xué)習(xí)Java中  
空指針(Null Pointer Exception,NPE)是Java中最常見(jiàn)不過(guò)的異常了,其原因雖然顯而易見(jiàn),但是開(kāi)發(fā)人員往往會(huì)忽略,或未能及時(shí)采取措施,下面這篇文章主要給大家介紹了關(guān)于Java中空指針異常該如何避免的相關(guān)資料,需要的朋友可以參考下

Java中如何避免空指針異常,這也是由初級(jí)程序員成長(zhǎng)到中級(jí)程序員的時(shí)候經(jīng)常會(huì)遇到的問(wèn)題。

程序員不知道或不信任正在使用的約定,并且小心的檢查著null。還有當(dāng)程序員寫(xiě)代碼的時(shí)候,總是會(huì)依賴于通過(guò)返回空(NULL)來(lái)表明某些意義,因此需要調(diào)用者去檢查Null。

有兩種空指針的檢查場(chǎng)景:

  • 期望的結(jié)果就是null。
  • 期望的結(jié)果不是null。

第二種很簡(jiǎn)單,可以通過(guò)用assert或者允許程序報(bào)錯(cuò),例如拋出NullPointerException。Assertions是一個(gè)從Java1.4加進(jìn)來(lái)的高度未被利用的特性,語(yǔ)法是:

assert <condition>

或者

assert <condition> : <object>

condition是一個(gè)布爾表達(dá)式,object是一個(gè)對(duì)象(其toString()方法的輸出將會(huì)被包含在錯(cuò)誤里)。

校對(duì)注:我測(cè)試了下,JDK1.4及其以上,運(yùn)行前設(shè)置vm參數(shù)-ea

public static void main(String[] args) {String name = null;assert (name != null) : "name為空null";}
Exception in thread "main"; java.lang.AssertionError: 變量name為空nullat LogUtil.main(LogUtil.java:37)

如果condition為false的話,assert將會(huì)拋出一個(gè)Error(AssertionError)。默認(rèn)Java會(huì)忽略斷言你可以通過(guò)在JVM中傳入一個(gè)-ea參數(shù)來(lái)啟用斷言。

你可以為單獨(dú)的一個(gè)包或者類啟動(dòng)關(guān)閉assertions。這意味著你可以在開(kāi)發(fā)和測(cè)試的時(shí)候通過(guò)斷言來(lái)驗(yàn)證代碼,在發(fā)布產(chǎn)品的時(shí)候關(guān)閉它,盡管我下面展示的測(cè)試中并沒(méi)有因?yàn)閍ssertions而損失性能。在這個(gè)代碼段中不用斷言也可以,因?yàn)樗麜?huì)運(yùn)行失敗的,就像加了斷言一樣。唯一的區(qū)別是有了斷言可能會(huì)發(fā)生的更快一些,更有意義,并且會(huì)附加一些額外的信息,而這可以幫助你弄明白失敗的原因。

第一種有一點(diǎn)棘手。如果你對(duì)不能控制正在調(diào)用的這段代碼,那你就卡住了。如果Null是一個(gè)合理的返回值,你就應(yīng)該檢查它。如果是你能夠控制的代碼,那就是個(gè)完全不同的故事情景了。盡量避免用NULL作為返回值。對(duì)于返回Collections的集合很容易,返回Empty(一個(gè)空集合或者數(shù)組),而不是一直用null作為返回值。對(duì)于不是返回Collections的方法會(huì)有一點(diǎn)復(fù)雜??紤]下面這個(gè)例子:

public interface Action {
  void doSomething();}public interface Parser {
  Action findAction(String userInput);}

Parser采用用戶的輸入作為參數(shù),然后做一些事情(例如模擬一個(gè)命令行)?,F(xiàn)在你可能會(huì)返回null,如果沒(méi)找到對(duì)應(yīng)輸入的動(dòng)作的話,這就導(dǎo)致了剛才說(shuō)過(guò)的空指針檢查。

一個(gè)可選的解決方案是永遠(yuǎn)不要返回null,而是返回一個(gè)空對(duì)象

public class MyParser implements Parser {
  private static Action DO_NOTHING = new Action() {
    public void doSomething() { /* do nothing */ }
  };

  public Action findAction(String userInput) {
    // ...
    if ( /* we can't find any actions */ ) {
      return DO_NOTHING;
    }
  }}

比較這段代碼:

Parser parser = ParserFactory.getParser();if (parser == null) {
  // now what?
  // this would be an example of where null isn't (or shouldn't be) a valid response}Action action = parser.findAction(someInput);if (action == null) {
  // do nothing} else {
  action.doSomething();}

和這段:

ParserFactory.getParser().findAction(someInput).doSomething();

這是個(gè)更好的設(shè)計(jì),因?yàn)樽銐蚝?jiǎn)潔,避免了多余的判斷。

即便如此,或許比較合適的設(shè)計(jì)是:findAction()方法之惡杰拋出一個(gè)異常,其中包含一些有意義的錯(cuò)誤信息—–特別是在這個(gè)案例中你依賴于用戶的輸入。

讓findAction()方法拋出一個(gè)異常而不是簡(jiǎn)單的產(chǎn)生一個(gè)沒(méi)有任何解釋的NullPointerException 要好得多。

try {
    ParserFactory.getParser().findAction(someInput).doSomething();} catch(ActionNotFoundException anfe) {
    userConsole.err(anfe.getMessage());}

或者你認(rèn)為try/catch 的機(jī)制太丑了,你的action應(yīng)該跟用戶提供一個(gè)反饋而不是什么都不做:

public Action findAction(final String userInput) {
    /* Code to return requested Action if found */
    return new Action() {
        public void doSomething() {
            userConsole.err("Action not found: " + userInput);
        }
    }}

補(bǔ)充:個(gè)人在做項(xiàng)目時(shí),對(duì)NullPointerException的幾點(diǎn)總結(jié),請(qǐng)網(wǎng)友拍磚?。。《喽嗵嵋庖?jiàn),

1.對(duì)于別人接口的返回對(duì)象要做非空判斷,因?yàn)槲覀儾磺宄@得的對(duì)象會(huì)不會(huì)為空,對(duì)于Collection Map 我一般會(huì)調(diào)用CollectionUtils MapUtils ,對(duì)于返回的String對(duì)象,我會(huì)調(diào)StringUtils.isNotEmpty()進(jìn)行非空判斷。他們中isNotEmpty不僅判斷了NULL 還判斷了空集合和空串。例如從數(shù)據(jù)中查詢的結(jié)果。工作流中返回的定價(jià)URL

2. 對(duì)于自己創(chuàng)建的對(duì)象,要留心對(duì)象進(jìn)行哪些操作,中間會(huì)不會(huì)造成對(duì)象為空,如果可能加非空判斷,尤其是對(duì)于集合的操作,很容易就報(bào)空指針?。?!所以每次對(duì)操作集合時(shí),我都會(huì)非常的留心。

3. 對(duì)于前臺(tái)的領(lǐng)域?qū)ο笠浅5牧粜?,因?yàn)檫@些對(duì)象是框架創(chuàng)建的,假如我沒(méi)有在前臺(tái)的文本框內(nèi)輸入值,雖然提交時(shí)后臺(tái)獲得的是空串,但發(fā)生NullPointerException的概率很高。

4. 對(duì)于String 的操作盡量使用apache 的StringUtils類,與String相比這個(gè)是非常的安全。對(duì)于集合的操作使用apache的CollectionUtils 、MapUtils, 相比apache工具類的執(zhí)行效率也非常的高,比如StringUtils.split();

有人說(shuō)過(guò)多的判斷會(huì)影響性能,我個(gè)人認(rèn)為這里的性能犧牲和系統(tǒng)的安全相比是微不足道的。

總結(jié)

到此這篇關(guān)于Java中空指針異常該如何避免的文章就介紹到這了,更多相關(guān)Java空指針異常內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • ActiveMQ結(jié)合Spring收發(fā)消息的示例代碼

    ActiveMQ結(jié)合Spring收發(fā)消息的示例代碼

    這篇文章主要介紹了ActiveMQ結(jié)合Spring收發(fā)消息的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-10-10
  • SpringBoot整合Mybatis與MybatisPlus方法詳細(xì)講解

    SpringBoot整合Mybatis與MybatisPlus方法詳細(xì)講解

    這篇文章主要介紹了SpringBoot整合Mybatis與MybatisPlus方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2023-01-01
  • 淺談兩個(gè)jar包中包含完全相同的包名和類名的加載問(wèn)題

    淺談兩個(gè)jar包中包含完全相同的包名和類名的加載問(wèn)題

    下面小編就為大家?guī)?lái)一篇淺談兩個(gè)jar包中包含完全相同的包名和類名的加載問(wèn)題。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-09-09
  • Spring實(shí)戰(zhàn)之使用Resource作為屬性操作示例

    Spring實(shí)戰(zhàn)之使用Resource作為屬性操作示例

    這篇文章主要介紹了Spring實(shí)戰(zhàn)之使用Resource作為屬性,結(jié)合實(shí)例形式分析了spring載人Resource作為屬性相關(guān)配置與使用技巧,需要的朋友可以參考下
    2020-01-01
  • 詳解Java的構(gòu)造方法及類的初始化

    詳解Java的構(gòu)造方法及類的初始化

    這篇文章主要為大家詳細(xì)介紹了Java的構(gòu)造方法及類的初始化,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Java有一定的幫助,感興趣的小伙伴可以了解一下
    2022-08-08
  • Java 在生活中的 10 大應(yīng)用

    Java 在生活中的 10 大應(yīng)用

    這篇文章主要給大家分享Java 在生活中的 10 大應(yīng)用,桌面圖形用戶界面、移動(dòng)應(yīng)用、人工智能、網(wǎng)絡(luò)應(yīng)用程序、大數(shù)據(jù)技術(shù)、游戲應(yīng)用、商業(yè)應(yīng)用、嵌入式系統(tǒng)、云應(yīng)用、科學(xué)應(yīng)用,下文來(lái)看具體應(yīng)用介紹,需要的朋友可以參考一下
    2021-11-11
  • 排序算法圖解之Java冒泡排序及優(yōu)化

    排序算法圖解之Java冒泡排序及優(yōu)化

    冒泡排序即通過(guò)對(duì)待排序的序列從前往后,依次比較相鄰元素的值,若發(fā)現(xiàn)逆序則交換位置,使較大的元素逐漸移動(dòng)到后部。本文通過(guò)圖片和示例介紹了冒泡排序的實(shí)現(xiàn)及優(yōu)化,需要的可以參考一下
    2022-11-11
  • SpringBoot使用CommandLineRunner接口完成資源初始化方式

    SpringBoot使用CommandLineRunner接口完成資源初始化方式

    這篇文章主要介紹了SpringBoot使用CommandLineRunner接口完成資源初始化方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • springboot整合SSE技術(shù)開(kāi)發(fā)小結(jié)

    springboot整合SSE技術(shù)開(kāi)發(fā)小結(jié)

    本文主要介紹了springboot整合SSE技術(shù)開(kāi)發(fā)小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-11-11
  • Springboot應(yīng)用中線程池配置詳細(xì)教程(最新2021版)

    Springboot應(yīng)用中線程池配置詳細(xì)教程(最新2021版)

    這篇文章主要介紹了Springboot應(yīng)用中線程池配置教程(2021版),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03

最新評(píng)論