Objects.requireNonNull的意義是什麼

簡直就是藝術發表於2022-11-24

Objects.requireNonNull方法的原始碼是這樣:

public static <T> T requireNonNull(T obj) {
    if (obj == null)
        throw new NullPointerException();
    return obj;
}

曾幾何時,我的想法是,這個判斷物件為 null,再丟擲NPE沒啥用啊,引數為null自然就會拋空指標異常,還用得著手動丟擲嗎?

其實是有意義的,總結就是:

  1. 明確程式碼意圖
  2. 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();
    }
}

使用哪種方式看團隊規範。

相關文章