為什么阿里巴巴要求 POJO 中不能使用基本數據類型?
在《阿里巴巴Java開發手冊》中,對于POJO中如何選擇變量的類型以及 RPC 接口中的返回值類型也有著一些規定:
這里強制要求使用包裝類型,原因是什么呢?
我們來看一段簡單的代碼:
/**
* @author Hollis
*/
public class BooleanMainTest {
public static void main(String[] args) {
Model model1 = new Model();
System.out.println("default model : " + model1);
}
}
class Model {
/**
* 定一個Boolean類型的success成員變量
*/
private Boolean success;
/**
* 定一個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();
}
}
以上代碼輸出結果為:
default model : Model[success=null, failure=false]
可以看到,當我們沒有設置Model對象的字段的值的時候,Boolean類型的變量會設置默認值為null,而boolean類型的變量會設置默認值為false。
即Boolean對象的默認值是null,boolean基本數據類型的默認值是false。
也就是說,包裝類型的默認值都是null,而基本數據類型的默認值是一個固定值,如boolean是false,byte、short、int、long是0,float是0.0f等;
我們再舉一個扣費的例子,我們做一個扣費系統,扣費時需要從外部的定價系統中通過 RPC 請求讀取一個費率的值,我們預期該接口的返回值中會包含一個浮點型的費率字段。當我們取到這個值得時候就使用公式:金額*費率=費用 進行計算,計算結果進行劃扣。
如果由于計費系統異常,他可能會返回個默認值,如果這個字段是Double類型的話,該默認值為null,如果該字段是double類型的話,該默認值為0.0。
如果扣費系統對于該費率返回值沒做特殊處理的話,拿到null值進行計算會直接報錯,阻斷程序。拿到0.0可能就直接進行計算,得出接口為0后進行扣費了。這種異常情況就無法被感知。
有人說,那我可以對0.0做特殊判斷,如果是0一樣可以阻斷報錯啊。但是,這時候就會產生一個問題,如果允許費率是0的場景又怎么處理呢?
所以,使用基本數據類型只會讓方案越來越復雜,坑越來越多。
這種使用包裝類型定義變量的方式,通過異常來阻斷程序,進而可以被識別到這種線上問題。如果使用基本數據類型的話,系統可能不會報錯,進而認為無異常。
當然,以上的選擇是針對一些電商、支付、金融等場景,可以犧牲暫時的可用性的場景,如果是對于某些軟件系統,可以容忍數據不準,但是不能系統不可用的情況要另當別論。
以上,就是要求在POJO和RPC的返回值中使用包裝類型的原因。