java 核心技術(shù)-12版 卷Ⅰ- 4.3.6 使用null 引用
????在4.2.1 節(jié)中,我們已經(jīng)了解到,對(duì)象變量包含一個(gè)對(duì)象的引用,或者包含一個(gè)特殊值null ,后者表示沒(méi)有引用任何對(duì)象。
????聽(tīng)上去這是一種處理特殊情況的便捷機(jī)制,如未知的名字或雇傭日期。不過(guò)使用null 值時(shí)要非常小心。
????如果對(duì)null 值應(yīng)用一個(gè)方法,會(huì)產(chǎn)生一個(gè) NullPointerException 異常。
這是一個(gè)很?chē)?yán)重的錯(cuò)誤,類(lèi)似于“索引越界”異常。如果你的程序沒(méi)有“捕獲”異常,那么程序就會(huì)終止。正常情況下,程序并不捕獲這些異常,而是依賴(lài)于程序員從一開(kāi)始就不要帶來(lái)異常。
????提示: 程序因 NullPointerException 異常終止時(shí),棧軌跡會(huì)顯示問(wèn)題出現(xiàn)在哪一行代碼中。從Java 17 開(kāi)始,錯(cuò)誤消息會(huì)包含有 null值的變量或方法名。例如,在以下調(diào)用中:
????String e = e.getHireDay().toString();
????錯(cuò)誤消息會(huì)告訴你e 是否為null 或 e.getHireDay是否返回null。
? ? 定義一個(gè)類(lèi)時(shí),最好清楚地知道哪些字段可能為null。在我們的例子中,我們不希望 name 或 hireDay 字段為null。(不用擔(dān)心 salary,它是基本類(lèi)型,不可能為null)
????hireDay 字段肯定是非null的,因?yàn)樗跏蓟癁橐粋€(gè)新的 LocalDate對(duì)象。但是,name 可能為null,如果調(diào)用構(gòu)造器時(shí)為 n 提供的實(shí)參是 null,name就會(huì)是 null。
????對(duì)此有兩種解決方法?!皩捜荨狈椒ㄊ前裯ull參數(shù)轉(zhuǎn)換為一個(gè)適當(dāng)?shù)姆?null :
????
Objects 提供了一個(gè)便利方法
????"嚴(yán)格"方法則干脆拒絕 null 參數(shù)
name = Objects.requireNonNullElse(n , "unknown");
????如果用null 名字構(gòu)造一個(gè) Employee 對(duì)象,就會(huì)產(chǎn)生NullPointerException 異常。乍看上去這種補(bǔ)救方法好像不太有用,不過(guò)這種方法有兩個(gè)好處:
????1. 異常報(bào)告會(huì)提供這個(gè)問(wèn)題的描述
????2.異常報(bào)告會(huì)準(zhǔn)確地指出問(wèn)題所在的位置,否則 NullPointerException異常會(huì)出現(xiàn)在其他地方,而很難追蹤到真正導(dǎo)致問(wèn)題的構(gòu)造器參數(shù)。
????注釋?zhuān)喝绻邮芤粋€(gè)對(duì)象引用作為構(gòu)造參數(shù),就要問(wèn)問(wèn)自己:是不是真的希望接受可有可無(wú)的值。如果不是,那么“嚴(yán)格”方法更合適。