为什么阿里巴巴开发手册中强制要求 POJO 类使用包装类型?NPE问题防范
背景:寫這個的原因,也是我這兩天湊巧看到的,雖然我一直有 alibaba Java 開發手冊,也看過不少次,但是一直沒有注意過這個問題😂
屬于那種看過,但又沒完全看過👰
一起來看看吧沖咯🏂
hxdm,我寫不出小故事😭,但是可不可以看在我寫了不少,還算實用的份上,給個贊👍啊。
在這里請xdm 喝 🥤啦
一、前言🚕
今天在寫一個AdvertVO類時,我當時用 id 是直接給了個 long,沒有使用用包裝類型,然后 idea 里面的 Alibaba Java Coding Guidelines 插件就直接給了個黃色波浪線,ALT+ENTER一看,阿里巴巴Java開發手冊 的提示說:
關于基本數據類型與包裝數據類型的使用標準如下:
?1) 所有的POJO類屬性必須使用包裝數據類型。
?2) RPC方法的返回值和參數必須使用包裝數據類型。
?3) 所有的局部變量推薦使用基本數據類型。
說明:POJO類屬性沒有初值是提醒使用者在需要使用時,必須自己顯式地進行賦值,任何NPE問題,或者入庫檢查,都由使用者來保證。
我剛看的時候,稍稍有點點沒完全理解這個意思(可能是我比較菜,沒有經歷過這樣的場景),然后為了搞懂自己心里的小疑惑😂,就👇
接下來我們弄一個簡單的例子來理解理解,之后再聊聊實際發生的場景,以及會產生的危害
二、例子🛵
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);}/*** 結果:* Integer ==> a1:null* int ==> a2:0* Boolean ==> b1:null* boolean ==> b2:false*/ }所有的包裝類型在我們沒有賦值的時候,都是直接默認 null 值的,而基本類型都會初始化一個默認值。
也就是說,包裝類型的默認值都是null,而基本數據類型的默認值是一個固定值,如boolean是false,byte、short、int、long是0,float是0.0f等;
👨?💻可能 xdm 平時有注意到,但又沒有完全注意到,用 基本類型和包裝類型之間的區別。下面我們用場景說一說區別:👩?🏫
三、場景🛫
【正例】:數據庫的查詢結果可能是 null,因為自動拆箱,用基本數據類型接收有 NPE 風險。( NPE 下文有解釋)
【反例】:某業務的交易報表上顯示成交總額漲跌情況,即正負 x%,x 為基本數據類型,調用的 RPC 服務,調用不成功時,返回的是默認值,頁面顯示為 0%,這是不合理的,應該顯示成中劃線-。所以包裝數據類型 的 null 值,能夠表示額外的信息,如:遠程調用失敗,異常退出。
1)場景一?
我們再舉一個扣費的例子,我們做一個扣費系統,扣費時需要從外部的定價系統中讀取一個費率的值,我們預期該接口的返回值中會包含一個浮點型的費率字段。當我們取到這個值得時候就使用公式:金額*費率=費用 進行計算,計算結果進行劃扣。
如果由于計費系統異常,他可能會返回個默認值,如果這個字段是Double類型的話,該默認值為null,如果該字段是double類型的話,該默認值為0.0。
如果扣費系統對于該費率返回值沒做特殊處理的話,拿到null值進行計算會直接報錯,阻斷程序。拿到0.0可能就直接進行計算,得出接口為0后進行扣費了。這種異常情況就無法被感知。
有人說,那我可以對0.0做特殊判斷,如果是0一樣可以阻斷報錯啊。但是,這時候就會產生一個問題,如果允許費率是0的場景又怎么處理呢?(如下例)
一個小小結論:使用基本類型可能會在一定程度上增大系統的復雜性,讓坑變得越來越多。
還有這種使用包裝類型定義變量的方式,通過異常來阻斷程序的運行,進而可以被立馬識別到這種綫上問題。但是我們如果使用基本數據類型的話,系統可能認為無異常,從而繼續運行。只能被動的測試出現問題,更甚的是如果是線上出現這種問題,我想可能…都明白哈。
2)場景二🌆
簡單來說就是我們如果自定義了一個 Student 類,其中有一個屬性是成績 score .
如果用 Integer 而不用 int 定義,一次考試,學生可能沒考,值是null,也可能考了,但考了0分,值是0.
public class Student {private Integer score;private int score; }請注意:這兩個表達的狀態明顯不一樣 。如果我們用包裝類型的話,null的話證明沒有考,0的話證明考了0分;但是如果我們用基本類型的話,這兩種情況都是一個樣的,沒法區分的。
四、NPE 問題🗽
【推薦】防止 NPE,是程序員的基本修養,注意 NPE 產生的場景:
NPE,指為基本類型的數據返回null值,防止NPE是程序員的基本休養。所有NPE的場景:
返回類型為基本數據類型,return包裝數據類型的對象時,自動拆箱有可能產生NPE。
public int f() {return Integer 對象;} 如果為null,自動解箱拋NPE。數據庫的查詢結果可能為 null。
集合里的元素即使 isNotEmpty,取出的數據元素也可能為 null。
遠程調用返回對象時,一律要求進行空指針判斷,防止 NPE。
對于 Session 中獲取的數據,建議進行 NPE 檢查,避免空指針。
級聯調用 obj.getA().getB().getC() ;一連串調用,易產生 NPE。
正例:使用 JDK8 的 Optional 類來防止 NPE 問題。了解👉JDK8 Optional 類
五、自言自語🚏
你好,我是博主寧在春:主頁
希望本篇文章能讓你感到有所收獲!!!
祝 我們:待別日相見時,都已有所成。
歡迎大家一起討論問題😁,躺了🛌
參考:Alibaba Java 開發手冊
總結
以上是生活随笔為你收集整理的为什么阿里巴巴开发手册中强制要求 POJO 类使用包装类型?NPE问题防范的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JUC系列(九)| ThreadPool
- 下一篇: JUC系列(十) | ForkJoin框