為什么阿里巴巴開發(fā)手冊(cè)中強(qiáng)制要求 POJO 類使用包裝類型?NPE問題防范

封面:學(xué)校內(nèi)的秋天

背景:寫這個(gè)的原因,也是我這兩天湊巧看到的,雖然我一直有 alibaba Java 開發(fā)手冊(cè),也看過不少次,但是一直沒有注意過這個(gè)問題??

屬于那種看過,但又沒完全看過??

一起來看看吧沖咯??

hxdm,我寫不出小故事??,但是可不可以看在我寫了不少,還算實(shí)用的份上,給個(gè)贊??啊。

在這里請(qǐng)xdm 喝 ??啦

一、前言??

image-20211013210702451

今天在寫一個(gè)AdvertVO類時(shí),我當(dāng)時(shí)用 id 是直接給了個(gè) long,沒有使用用包裝類型,然后 idea 里面的 Alibaba Java Coding Guidelines 插件就直接給了個(gè)黃色波浪線,ALT+ENTER一看,阿里巴巴Java開發(fā)手冊(cè) 的提示說:

關(guān)于基本數(shù)據(jù)類型與包裝數(shù)據(jù)類型的使用標(biāo)準(zhǔn)如下:
?1) 所有的POJO類屬性必須使用包裝數(shù)據(jù)類型。
?2) RPC方法的返回值和參數(shù)必須使用包裝數(shù)據(jù)類型。
?3) 所有的局部變量推薦使用基本數(shù)據(jù)類型。

說明:POJO類屬性沒有初值是提醒使用者在需要使用時(shí),必須自己顯式地進(jìn)行賦值,任何NPE問題,或者入庫檢查,都由使用者來保證。

我剛看的時(shí)候,稍稍有點(diǎn)點(diǎn)沒完全理解這個(gè)意思(可能是我比較菜,沒有經(jīng)歷過這樣的場(chǎng)景),然后為了搞懂自己心里的小疑惑??,就??

image-20211013212155710

接下來我們弄一個(gè)簡單的例子來理解理解,之后再聊聊實(shí)際發(fā)生的場(chǎng)景,以及會(huì)產(chǎn)生的危害

二、例子??

public class Main {
    private static Integer a1;
    private static int a2;

    private static Boolean b1;
    private static boolean b2;
  
    public static void main(String[] args) {
        System.out.println("Integer ==> a1:"+a1);
        System.out.println("int     ==> a2:"+a2);
        System.out.println("Boolean ==> b1:"+b1);
        System.out.println("boolean ==> b2:"+b2);
    }
    /**
     * 結(jié)果:
     * Integer ==> a1:null
     * int     ==> a2:0
     * Boolean ==> b1:null
     * boolean ==> b2:false
     */
}

所有的包裝類型在我們沒有賦值的時(shí)候,都是直接默認(rèn) null 值的,而基本類型都會(huì)初始化一個(gè)默認(rèn)值。

也就是說,包裝類型的默認(rèn)值都是null,而基本數(shù)據(jù)類型的默認(rèn)值是一個(gè)固定值,如boolean是false,byte、short、int、long是0,float是0.0f等;

????可能 xdm 平時(shí)有注意到,但又沒有完全注意到,用 基本類型和包裝類型之間的區(qū)別。下面我們用場(chǎng)景說一說區(qū)別:????

三、場(chǎng)景??

【正例】:數(shù)據(jù)庫的查詢結(jié)果可能是 null,因?yàn)樽詣?dòng)拆箱,用基本數(shù)據(jù)類型接收有 NPE 風(fēng)險(xiǎn)。( NPE 下文有解釋)

【反例】:某業(yè)務(wù)的交易報(bào)表上顯示成交總額漲跌情況,即正負(fù) x%,x 為基本數(shù)據(jù)類型,調(diào)用的 RPC 服務(wù),調(diào)用不成功時(shí),返回的是默認(rèn)值,頁面顯示為 0%,這是不合理的,應(yīng)該顯示成中劃線-。所以包裝數(shù)據(jù)類型 的 null 值,能夠表示額外的信息,如:遠(yuǎn)程調(diào)用失敗,異常退出。

1)場(chǎng)景一?

我們?cè)倥e一個(gè)扣費(fèi)的例子,我們做一個(gè)扣費(fèi)系統(tǒng),扣費(fèi)時(shí)需要從外部的定價(jià)系統(tǒng)中讀取一個(gè)費(fèi)率的值,我們預(yù)期該接口的返回值中會(huì)包含一個(gè)浮點(diǎn)型的費(fèi)率字段。當(dāng)我們?nèi)〉竭@個(gè)值得時(shí)候就使用公式:金額*費(fèi)率=費(fèi)用 進(jìn)行計(jì)算,計(jì)算結(jié)果進(jìn)行劃扣。

如果由于計(jì)費(fèi)系統(tǒng)異常,他可能會(huì)返回個(gè)默認(rèn)值,如果這個(gè)字段是 Double 類型的話,該默認(rèn)值為 null ,如果該字段是 double 類型的話,該默認(rèn)值為 0.0。

如果扣費(fèi)系統(tǒng)對(duì)于該費(fèi)率返回值沒做特殊處理的話,拿到null值進(jìn)行計(jì)算會(huì)直接報(bào)錯(cuò),阻斷程序。拿到 0.0可能就直接進(jìn)行計(jì)算,得出接口為 0 后進(jìn)行扣費(fèi)了。這種異常情況就無法被感知。

有人說,那我可以對(duì) 0.0 做特殊判斷,如果是 0 一樣可以阻斷報(bào)錯(cuò)啊。但是,這時(shí)候就會(huì)產(chǎn)生一個(gè)問題,如果允許費(fèi)率是 0 的場(chǎng)景又怎么處理呢?(如下例)

一個(gè)小小結(jié)論:使用基本類型可能會(huì)在一定程度上增大系統(tǒng)的復(fù)雜性,讓坑變得越來越多。
還有這種使用包裝類型定義變量的方式,通過異常來阻斷程序的運(yùn)行,進(jìn)而可以被立馬識(shí)別到這種綫上問題。但是我們?nèi)绻褂没緮?shù)據(jù)類型的話,系統(tǒng)可能認(rèn)為無異常,從而繼續(xù)運(yùn)行。只能被動(dòng)的測(cè)試出現(xiàn)問題,更甚的是如果是線上出現(xiàn)這種問題,我想可能...都明白哈。

2)場(chǎng)景二??

簡單來說就是我們?nèi)绻远x了一個(gè) Student 類,其中有一個(gè)屬性是成績 score .

如果用 Integer 而不用 int 定義,一次考試,學(xué)生可能沒考,值是null,也可能考了,但考了0分,值是0.

public class Student  {

    private  Integer score;

    private  int score;
}

請(qǐng)注意這兩個(gè)表達(dá)的狀態(tài)明顯不一樣 。如果我們用包裝類型的話,null的話證明沒有考,0的話證明考了0分;但是如果我們用基本類型的話,這兩種情況都是一個(gè)樣的,沒法區(qū)分的。

四、NPE 問題??

【推薦】防止 NPE,是程序員的基本修養(yǎng),注意 NPE 產(chǎn)生的場(chǎng)景:

NPE,指為基本類型的數(shù)據(jù)返回null值,防止NPE是程序員的基本休養(yǎng)。所有NPE的場(chǎng)景:

  1. 返回類型為基本數(shù)據(jù)類型,return包裝數(shù)據(jù)類型的對(duì)象時(shí),自動(dòng)拆箱有可能產(chǎn)生NPE。

    public int f() {
          return Integer 對(duì)象;
     } 
    如果為null,自動(dòng)解箱拋NPE。
    
    
  2. 數(shù)據(jù)庫的查詢結(jié)果可能為 null。

  3. 集合里的元素即使 isNotEmpty,取出的數(shù)據(jù)元素也可能為 null。

  4. 遠(yuǎn)程調(diào)用返回對(duì)象時(shí),一律要求進(jìn)行空指針判斷,防止 NPE。

  5. 對(duì)于 Session 中獲取的數(shù)據(jù),建議進(jìn)行 NPE 檢查,避免空指針。

  6. 級(jí)聯(lián)調(diào)用 obj.getA().getB().getC() ;一連串調(diào)用,易產(chǎn)生 NPE。

正例:使用 JDK8 的 Optional 類來防止 NPE 問題。了解??JDK8 Optional 類

五、自言自語??

你好,我是博主寧在春主頁

希望本篇文章能讓你感到有所收獲!!!

我們:待別日相見時(shí),都已有所成。

歡迎大家一起討論問題??,躺了??

image-20211014091239193

參考:Alibaba Java 開發(fā)手冊(cè)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容