新來了個(gè)技術(shù)總監(jiān):誰再在 POJO 中使用基本數(shù)據(jù)類型,以后就不用來了!
大家好,我是程序汪
程序員編碼時(shí)一些不經(jīng)意的細(xì)節(jié)可能導(dǎo)致一些很難察覺的BUG,上生產(chǎn)運(yùn)行一段時(shí)間后才發(fā)現(xiàn),真的很頭疼。
在《阿里巴巴Java開發(fā)手冊(cè)》中,對(duì)于POJO中如何選擇變量的類型以及 RPC 接口中的返回值類型也有著一些規(guī)定:

這里強(qiáng)制要求使用包裝類型,原因是什么呢?
我們來看一段簡(jiǎn)單的代碼
/**
?*?@author?Hollis
?*/
public?class?BooleanMainTest?{
????public?static?void?main(String[]?args)?{
????????Model?model1?=?new?Model();
????????System.out.println("default?model?:?"?+?model1);
????}
}
class?Model?{
????/**
?????*?定一個(gè)Boolean類型的success成員變量
?????*/
????private?Boolean?success;
????/**
?????*?定一個(gè)boolean類型的failure成員變量
?????*/
????private?boolean?failure;
????/**
?????*?覆蓋toString方法,使用Java?8?的StringJoiner
?????*/
????@Override
????public?String?toString()?{
????????return?new?StringJoiner(",?",?Model.class.getSimpleName()?+?"[",?"]")
????????????????.add("success="?+?success)
????????????????.add("failure="?+?failure)
????????????????.toString();
????}
}
以上代碼輸出結(jié)果為:
default?model?:?Model[success=null,?failure=false]
可以看到,當(dāng)我們沒有設(shè)置Model對(duì)象的字段的值的時(shí)候,Boolean類型的變量會(huì)設(shè)置默認(rèn)值為null,而boolean類型的變量會(huì)設(shè)置默認(rèn)值為false。
即Boolean對(duì)象的默認(rèn)值是null,boolean基本數(shù)據(jù)類型的默認(rèn)值是false。
也就是說,包裝類型的默認(rèn)值都是null,而基本數(shù)據(jù)類型的默認(rèn)值是一個(gè)固定值,如boolean是false,byte、short、int、long是0,float是0.0f等;
我們?cè)倥e一個(gè)扣費(fèi)的例子,我們做一個(gè)扣費(fèi)系統(tǒng),扣費(fèi)時(shí)需要從外部的定價(jià)系統(tǒng)中通過 RPC 請(qǐ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)景又怎么處理呢?
所以,使用基本數(shù)據(jù)類型只會(huì)讓方案越來越復(fù)雜,坑越來越多。
這種使用包裝類型定義變量的方式,通過異常來阻斷程序,進(jìn)而可以被識(shí)別到這種線上問題。如果使用基本數(shù)據(jù)類型的話,系統(tǒng)可能不會(huì)報(bào)錯(cuò),進(jìn)而認(rèn)為無異常。
當(dāng)然,以上的選擇是針對(duì)一些電商、支付、金融等場(chǎng)景,可以犧牲暫時(shí)的可用性的場(chǎng)景,如果是對(duì)于某些軟件系統(tǒng),可以容忍數(shù)據(jù)不準(zhǔn),但是不能系統(tǒng)不可用的情況要另當(dāng)別論。
以上,就是要求在POJO和RPC的返回值中使用包裝類型的原因。
程序汪資料鏈接
程序汪接的7個(gè)私活都在這里,經(jīng)驗(yàn)整理
Java項(xiàng)目分享 ?最新整理全集,找項(xiàng)目不累啦 07版
堪稱神級(jí)的Spring Boot手冊(cè),從基礎(chǔ)入門到實(shí)戰(zhàn)進(jìn)階
臥槽!字節(jié)跳動(dòng)《算法中文手冊(cè)》火了,完整版 PDF 開放下載!
臥槽!阿里大佬總結(jié)的《圖解Java》火了,完整版PDF開放下載!
字節(jié)跳動(dòng)總結(jié)的設(shè)計(jì)模式 PDF 火了,完整版開放下載!
歡迎添加程序汪個(gè)人微信 itwang009? 進(jìn)粉絲群或圍觀朋友圈
