Objects.requireNonNull
方法的原始碼是這樣:
public static <T> T requireNonNull(T obj) {
if (obj == null)
throw new NullPointerException();
return obj;
}
曾幾何時,我的想法是,這個判斷物件為 null
,再丟擲NPE沒啥用啊,引數為null自然就會拋空指標異常,還用得著手動丟擲嗎?
其實是有意義的,總結就是:
- 明確程式碼意圖
- Fail-fast 快速失敗
Objects.requireNonNull
讓方法的呼叫者明確某個引數不能為 null
。比如,寫方法的單元測試,不需要考慮方法引數為null的場景,因為這個場景的是受控的,是不允許的。
Fail-fast的意思是讓程式碼儘可能早的發生失敗,而不是在中途失敗。Fail-fast的好處,首先是能立即且穩定的檢測出程式碼的問題,程式碼立即報錯,避免了無用的程式碼操作。在平時寫業務程式碼時,校驗邏輯儘可能放在方法前,避免業務在校驗不透過前,做了無用操作。比如:
public String getUserName(User user, String countryCode) {
queryCountry(countryCode);
return getUserLastName(user);
}
public String getUserLastName(User user) {
return user.getName().getLastName();
}
user為 null
時, queryCountry
就是無用操作。
Fail-fast能快速定位錯誤位置,也方便Dubug。如果user引數為 null
,你能定位到哪一行報錯,但還不能確保是user還是user.getName()的問題,所以你要去除錯。如果變數的引用層級更深,定位問題源就更麻煩。如果在源頭處控制了user的行為,那麼後續操作就令人放心。從另一方面講,也提升了程式的穩定性。
最後, lombok的@NonNull
註解也有這樣的功能。比如:
public int getLength(@NonNull String str) {
return str.length();
}
編譯後的效果是:
public int getLength(@NonNull String str) {
if (str == null) {
throw new NullPointerException("str is marked non-null but is null");
} else {
return str.length();
}
}
使用哪種方式看團隊規範。