最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java14發(fā)布了,再也不怕NullPointerException了

 更新時間:2020年03月26日 10:44:42   作者:Hollis  
這篇文章主要介紹了Java14發(fā)布了,再也不怕NullPointerException了,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

2020年3月17日發(fā)布,Java正式發(fā)布了JDK 14 ,目前已經(jīng)可以開放下載。在JDK 14中,共有16個新特性,本文主要來介紹其中的一個特性:JEP 358: Helpful NullPointerExceptions

null何錯之有?

對于Java程序員來說,null是令人頭痛的東西。時常會受到空指針異常(NullPointerException)的騷擾。相信很多程序員都特別害怕出現(xiàn)程序中出現(xiàn)NPE,因?yàn)檫@種異常往往伴隨著代碼的非預(yù)期運(yùn)行。

在編程語言中,空引用(Null Reference)是一個與空指針類似的概念,是一個已宣告但其并未引用到一個有效對象的變量。

在Java 1 中就包含了了Null引用和NPE了,但是其實(shí),Null引用是偉大的計(jì)算機(jī)科學(xué)家Tony Hoare 早在1965年發(fā)明的,最初作為編程語言ALGOL W的一部分。

1965年,英國一位名為Tony Hoare的計(jì)算機(jī)科學(xué)家在設(shè)計(jì)ALGOL W語言時提出了null引用的想法。ALGOL W是第一批在堆上分配記錄的類型語言之一。Hoare選擇null引用這種方式,“只是因?yàn)檫@種方法實(shí)現(xiàn)起來非常容易”。雖然他的設(shè)計(jì)初衷就是要“通過編譯器的自動檢測機(jī)制,確保所有使用引用的地方都是絕對安全的”,他還是決定為null引用開個綠燈,因?yàn)樗J(rèn)為這是為“不存在的值”建模最容易的方式。

但是在2009年,很多年后,他開始為自己曾經(jīng)做過這樣的決定而后悔不已,把它稱為“一個價(jià)值十億美元的錯誤”。實(shí)際上,Hoare的這段話低估了過去五十年來數(shù)百萬程序員為修復(fù)空引用所耗費(fèi)的代價(jià)。因?yàn)樵贏LGOL W之后出現(xiàn)的大多數(shù)現(xiàn)代程序設(shè)計(jì)語言,包括Java,都采用了同樣的設(shè)計(jì)方式,其原因是為了與更老的語言保持兼容,或者就像Hoare曾經(jīng)陳述的那樣,“僅僅是因?yàn)檫@樣實(shí)現(xiàn)起來更加容易”。

相信很多Java程序員都一樣對null和NPE深惡痛絕,因?yàn)樗_實(shí)會帶來各種各樣的問題(來自《Java 8 實(shí)戰(zhàn)》)。如:

  • 它是錯誤之源。 NullPointerException是目前Java程序開發(fā)中最典型的異常。它會使你的代碼膨脹。
  • 它讓你的代碼充斥著深度嵌套的null檢查,代碼的可讀性糟糕透頂。
  • 它自身是毫無意義的。 null自身沒有任何的語義,尤其是是它代表的是在靜態(tài)類型語言中以一種錯誤的方式對缺失變量值的建模。
  • 它破壞了Java的哲學(xué)。 Java一直試圖避免讓程序員意識到指針的存在,唯一的例外是:null指針。
  • 它在Java的類型系統(tǒng)上開了個口子。 null并不屬于任何類型,這意味著它可以被賦值給任意引用類型的變量。這會導(dǎo)致問題, 原因是當(dāng)這個變量被傳遞到系統(tǒng)中的另一個部分后,你將無法獲知這個null變量最初賦值到底是什么類型。

其他語言如何解決NPE問題

我們知道,出了Java語言外,還有很多其他的面向?qū)ο笳Z言,那么在其他的一些語言中,是如何解決NPE的問題的呢?

如在Groovy中使用安全導(dǎo)航操作符(Safe Navigation Operator)可以訪問可能為null的變量:

def carInsuranceName = person?.car?.insurance?.name

Groovy的安全導(dǎo)航操作符能夠避免在訪問這些可能為null引用的變量時發(fā)生NullPointerException,在調(diào)用鏈中的變量遭遇null時將null引用沿著調(diào)用鏈傳遞下去,返回一個null。

其實(shí)這個功能曾經(jīng)考慮過增加一個類似的功能,但是后來又被舍棄了。

另外,在Haskell和Scala也有類似的替代品,如Haskell中的Maybe類型、Scala中的Option[T]。

在 Kotlin 中,其類型系統(tǒng)嚴(yán)格區(qū)分一個引用可以容納 null 還是不能容納。也就是說,一個變量是否可空必須顯示聲明,對于可空變量,在訪問其成員時必須做空處理,否則無法編譯通過:

var a: String = "abc"
a = null // 編譯錯誤

果允許為空,可以聲明一個可空字符串,寫作 String?:

var b: String? = "abc" //String? 表示該 String 類型變量可為空
b = null // 編譯通過

看到這個?的時候,是不是發(fā)現(xiàn)和Groovy有點(diǎn)像?不過還是有一定區(qū)別的,這里就不展開了。

好了,書歸正傳,我們來看看作為一個TOIBE編程語言排行榜第一名的語言,Java語言對于NPE做出了哪些努力!

Java做了哪些努力

一直以來對于null和NPE的改進(jìn)還是做出了一些努力的。

首先在Java 8中提供了Optional,其實(shí)在Java 8 推出之前,Google的Guava庫中就率先提供過Optional接口來使null快速失敗。

Optional在可能為null的對象上做了一層封裝,Optional對象包含了一些方法來顯式地處理某個值是存在還是缺失,Optional類強(qiáng)制你思考值不存在的情況,這樣就能避免潛在的空指針異常。

但是設(shè)計(jì)Optional類的目的并不是完全取代null,它的目的是設(shè)計(jì)更易理解的API。通過Optional,可以從方法簽名就知道這個函數(shù)有可能返回一個缺失的值,這樣強(qiáng)制你處理這些缺失值的情況。

關(guān)于Optional的用法,不是本文的重點(diǎn),就不在這里詳細(xì)介紹了,筆者在日常開發(fā)中經(jīng)常結(jié)合Stream一起使用Optional,還是比較好用的。

另外一個值得一提的就是最近(2020年03月17日)發(fā)布的JDK 14中對于NPE有了一個增強(qiáng)。那就是JEP 358: Helpful NullPointerExceptions

更有幫助的NPE

JDK 14中對于NEP有了一個增強(qiáng),既然NPE暫時無法避免,那么就讓他對開發(fā)者更有幫助一些。

每個Java開發(fā)人員都遇到過NullPointerExceptions (NPEs)。由于NPEs可以發(fā)生在程序的幾乎任何地方,試圖捕獲并從它們中恢復(fù)通常是不切實(shí)際的。因此,開發(fā)人員通常依賴于JVM來確定NPE實(shí)際發(fā)生時的來源。例如,假設(shè)在這段代碼中出現(xiàn)了一個NPE:

a.i = 99;

JVM將打印出導(dǎo)致NPE的方法、文件名和行號:

Exception in thread "main" java.lang.NullPointerException
at Prog.main(Prog.java:5)

通過以上堆棧信息,開發(fā)人員可以定位到a.i= 99這一行,并推斷出a一定是null。

但是,對于更復(fù)雜的代碼,如果不使用調(diào)試器,就不可能確定哪個變量是null。假設(shè)在這段代碼中出現(xiàn)了一個NPE:

a.b.c.i = 99;

我們根本無法確定到底是a還是b或者是c在運(yùn)行時是個null值。

但是,在JDK14以后,這種窘境就有解了。

在JDK14中,當(dāng)運(yùn)行期,試圖對一個bull對象進(jìn)行應(yīng)用時,JVM依然會拋出一個NullPointerException (NPE),除此之外,還會通過通過分析程序的字節(jié)碼指令,JVM將精確地確定哪個變量是null,并且在堆棧信息中明確的提示出來。

在JDK 14中,如果上文中的a.i = 99發(fā)生NPE,將會打印如下堆棧:

Exception in thread "main" java.lang.NullPointerException:
Cannot assign field "i" because "a" is null
at Prog.main(Prog.java:5)

如果是a.b.c.i = 99;中的b為null導(dǎo)致了空指針,則會打印以下堆棧信息:

Exception in thread "main" java.lang.NullPointerException:
Cannot read field "c" because "a.b" is null
at Prog.main(Prog.java:5)

可見,堆棧中明確指出了到底是哪個對象為null而導(dǎo)致了NPE,這樣,一旦應(yīng)用中發(fā)生NPE,開發(fā)者可以通過堆棧信息第一時間定位到到底是代碼中的那個對象為null導(dǎo)致的。

這算是JDK的一個小小的改進(jìn),但是這個改進(jìn)對于開發(fā)者來說確實(shí)是非常友好的。真的希望這些小而美的改動可以在JDK中越來越多。

參考資料:

https://openjdk.java.net/jeps/358

《Java 8 In Action》

到此這篇關(guān)于Java14發(fā)布了,再也不怕NullPointerException了的文章就介紹到這了,更多相關(guān)Java14 NullPointerException內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 在AOP中Spring生成代理類的兩種方式

    在AOP中Spring生成代理類的兩種方式

    今天小編就為大家分享一篇關(guān)于在AOP中Spring生成代理類的兩種方式,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • 多線程下怎樣保證OkHttpClient的線程安全

    多線程下怎樣保證OkHttpClient的線程安全

    這篇文章主要介紹了多線程下怎樣保證OkHttpClient的線程安全問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • Java子線程無法獲取Attributes的解決方法(最新推薦)

    Java子線程無法獲取Attributes的解決方法(最新推薦)

    在Java多線程編程中,子線程無法直接獲取主線程設(shè)置的Attributes是一個常見問題,本文探討了這一問題的原因,并提供了兩種解決方案,對Java子線程無法獲取Attributes的解決方案感興趣的朋友一起看看吧
    2025-01-01
  • Springboot自定義mybatis攔截器實(shí)現(xiàn)擴(kuò)展

    Springboot自定義mybatis攔截器實(shí)現(xiàn)擴(kuò)展

    本文主要介紹了Springboot自定義mybatis攔截器實(shí)現(xiàn)擴(kuò)展,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • java異常繼承何類,運(yùn)行時異常與一般異常的區(qū)別(詳解)

    java異常繼承何類,運(yùn)行時異常與一般異常的區(qū)別(詳解)

    下面小編就為大家?guī)硪黄猨ava異常繼承何類,運(yùn)行時異常與一般異常的區(qū)別(詳解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-11-11
  • Spring BeanPostProcessor(后置處理器)的用法

    Spring BeanPostProcessor(后置處理器)的用法

    這篇文章主要介紹了Spring BeanPostProcessor(后置處理器)的用法,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • SpringBoot3使用devtools實(shí)現(xiàn)代碼熱部署的詳細(xì)步驟

    SpringBoot3使用devtools實(shí)現(xiàn)代碼熱部署的詳細(xì)步驟

    Spring Boot DevTools是一組用于提高開發(fā)人員生產(chǎn)力,并加速Spring Boot應(yīng)用程序開發(fā)的工具,它提供了一些功能,可以幫助開發(fā)人員更快速地構(gòu)建應(yīng)用程序,并減少常見的開發(fā)問題,本文給大家介紹了SpringBoot3使用devtools實(shí)現(xiàn)代碼熱部署的詳細(xì)步驟,需要的朋友可以參考下
    2024-01-01
  • Spring注解方式無法掃描Service注解的解決

    Spring注解方式無法掃描Service注解的解決

    這篇文章主要介紹了Spring注解方式無法掃描Service注解的解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Messges Queue消息隊(duì)列詳解

    Messges Queue消息隊(duì)列詳解

    這篇文章主要介紹了Messges Queue消息隊(duì)列詳解,消息隊(duì)列一般簡稱為 MQ,是指利用高效可靠的消息傳遞機(jī)制進(jìn)行與平臺無關(guān)的數(shù)據(jù)交流,并基于數(shù)據(jù)通信來進(jìn)行分布式系統(tǒng)的集成,是在消息的傳輸過程中保存消息的容器,需要的朋友可以參考下
    2023-07-07
  • Java 數(shù)據(jù)類型及類型轉(zhuǎn)換的互相轉(zhuǎn)換實(shí)例代碼

    Java 數(shù)據(jù)類型及類型轉(zhuǎn)換的互相轉(zhuǎn)換實(shí)例代碼

    這篇文章主要介紹了Java 數(shù)據(jù)類型及類型轉(zhuǎn)換的互相轉(zhuǎn)換實(shí)例代碼,需要的朋友可以參考下
    2020-10-10

最新評論

子长县| 赤峰市| 怀化市| 仙游县| 宁陕县| 财经| 随州市| 左权县| 长乐市| 澄城县| 乌兰察布市| 梨树县| 威海市| 都江堰市| 土默特右旗| 伽师县| 原平市| 东乌珠穆沁旗| 仙桃市| 辰溪县| 南岸区| 桂东县| 乐业县| 綦江县| 公安县| 通许县| 桐城市| 东阿县| 金华市| 通江县| 建阳市| 青浦区| 景东| 独山县| 博野县| 西和县| 奉贤区| 陇南市| 博罗县| 达拉特旗| 高淳县|