本篇內(nèi)容主要講解“在Java8中怎么避開(kāi)空指針異?!?,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“在Java8中怎么避開(kāi)空指針異?!卑?
目前成都創(chuàng)新互聯(lián)已為成百上千的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)絡(luò)空間、網(wǎng)站改版維護(hù)、企業(yè)網(wǎng)站設(shè)計(jì)、隆陽(yáng)網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶(hù)導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶(hù)和合作伙伴齊心協(xié)力一起成長(zhǎng),共同發(fā)展。
前言
要說(shuō) Java 編程中哪個(gè)異常是你印象最深刻的,那 NullPointerException 空指針可以說(shuō)是臭名昭著的。不要說(shuō)初級(jí)程序員會(huì)碰到, 即使是中級(jí),專(zhuān)家級(jí)程序員稍不留神,就會(huì)掉入這個(gè)坑里。
Null 引用的發(fā)明者Tony Hoare 曾在 2009 年作出道歉聲明,聲明中表示,到目前為止,空指針異常大約給企業(yè)已造成數(shù)十億美元的損失。
下面是 Tony Hoare 的原話(huà):
我將 Null 引用的設(shè)計(jì)稱(chēng)為是一個(gè)數(shù)十億美元的錯(cuò)誤。1965 那年,我正在用面向?qū)ο笳Z(yǔ)言(ALGOL W) 設(shè)計(jì)首個(gè)功能全面的系統(tǒng)。當(dāng)時(shí)我的考量是,確保所有被使用的引用都是安全的,編譯器會(huì)自動(dòng)進(jìn)行檢查。但是,我沒(méi)有抵住誘惑,加入了 Null 引用,僅僅是為了實(shí)現(xiàn)起來(lái)省事。這之后,它導(dǎo)致了數(shù)不清的 bug、錯(cuò)誤和系統(tǒng)崩潰,也為企業(yè)導(dǎo)致了不可估量的損失。
事已至此,我們必須學(xué)會(huì)面對(duì)它。So, 我們要如何防止空指針異常呢?
唯一的辦法就是對(duì)可能為 Null 的對(duì)象添加檢查。但是 Null 檢查是繁瑣且痛苦的。所以一些比較新的語(yǔ)言為了處理 Null 檢查,特意添加了特殊的語(yǔ)法,如空合并運(yùn)算符。
在Groovy 或Kotlin 這樣的語(yǔ)言中也被稱(chēng)為 Elvis 運(yùn)算符。
不幸的是,在老版本的 Java 中并沒(méi)有提供這樣的語(yǔ)法糖。Java8 中在這方面做了改進(jìn)。所以,這篇文章就特意來(lái)介紹一下如何在 Java8 中利用新特性來(lái)編寫(xiě)防止 NullPointerException 的發(fā)生。
Java8 中如何加強(qiáng)對(duì) Null 對(duì)象的檢查?
在上篇文章 Java8 新特性指導(dǎo)手冊(cè) 中簡(jiǎn)單的提了一下如何通過(guò) Optional 類(lèi)來(lái)對(duì)對(duì)象做空校驗(yàn)。接下來(lái),我們?cè)偌?xì)說(shuō)一下:
在業(yè)務(wù)系統(tǒng)中,對(duì)象中嵌套對(duì)象是經(jīng)常發(fā)生的場(chǎng)景,如下示例代碼:
// 最外層對(duì)象class Outer { Nested nested; Nested getNested() { return nested; }}// 第二層對(duì)象class Nested { Inner inner; Inner getInner() { return inner; }}// 最底層對(duì)象class Inner { String foo; String getFoo() { return foo; }}
業(yè)務(wù)中,假設(shè)我們需要獲取 Outer 對(duì)象對(duì)底層的 Inner 中的 foo 屬性,我們必須寫(xiě)一堆的非空校驗(yàn),來(lái)防止發(fā)生 NullPointerException :
// 繁瑣的代碼Outer outer = new Outer();if (outer != null && outer.nested != null && outer.nested.inner != null) { System.out.println(outer.nested.inner.foo);}
通過(guò) Optional
在 Java8 中,我們有更優(yōu)雅的解決方式,那就是使用 Optional 是說(shuō),我們可以在一行代碼中,進(jìn)行流水式的 map 操作。而 map 方法內(nèi)部會(huì)自動(dòng)進(jìn)行空校驗(yàn) :
Optional.of(new Outer()) .map(Outer::getNested) .map(Nested::getInner) .map(Inner::getFoo .ifPresent(System.out::println); // 如果不為空,最終輸出 foo 的值
通過(guò) suppiler 函數(shù)自定義增強(qiáng) API
上面這種方式個(gè)人感覺(jué)還是有點(diǎn)啰嗦,我們可以利用 suppiler 函數(shù)來(lái)出一個(gè)終極解決方案:
public static
利用上面的 resolve 方法來(lái)重構(gòu)上述的非空校驗(yàn)代碼段:
Outer obj = new Outer();// 直接調(diào)用 resolve 方法,內(nèi)部做空指針的處理resolve(() -> obj.getNested().getInner().getFoo()); .ifPresent(System.out::println); // 如果不為空,最終輸出 foo 的值
到此,相信大家對(duì)“在Java8中怎么避開(kāi)空指針異?!庇辛烁畹牧私猓环羴?lái)實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢(xún),關(guān)注我們,繼續(xù)學(xué)習(xí)!