「技能分享」有效處理空值的10個技巧,學不會算我輸
1.不要過于復雜
就其本身而言,處理null可能是一個復雜的問題,因此我們應使其盡可能整潔和明顯。我在某些代碼庫中看到的一種非常糟糕的做法是在簡單的空檢查就足夠了的地方使用Objects方法,Optional類,甚至使用Optional的單獨方法。
這導致我檢查該方法的來源,包含的內容,并想知道此方法與直接比較之間的區別是什么。當然,您的里程可能會有所不同,但是對我來說,這是我們應該避免的大量開銷。
if (Optional.ofNullable(myVariable).isPresent()) // bad
if (Objects.nonNull(myVariable)) // better, but still bad
if (myVariable != null) // good
2.使用對象方法作為流謂詞
雖然對象isNull和Objects ,nonNull不是典型的null檢查的最佳選擇,它們非常適合與流一起使用。與之相比,使用它們進行過濾或匹配的行的讀取(可以說)要好得多。實際上,這就是在JDK中引入它們的原因。
myStream.filter(Objects::nonNull)
myStream.anyMatch(Objects::isNull)
3.永遠不要將Null作為參數
這是良好編碼的最重要原則之一,但是如果您還不了解它,就應該對它進行解釋。傳遞null表示給定參數沒有值可能是一個可行的選擇。但是它有兩個很大的缺點:
- 您需要閱讀該函數的實現,并弄清楚它以及可能受影響的每個函數能否正確處理空值。
- 在更改函數的實現時,您必須始終小心,不要丟掉可能為用戶處理空值的內容。否則,您必須搜索整個源代碼以檢查是否在任何地方傳遞了null。
通過接受永不傳遞null的原則,這兩個問題將永遠消失。那么帶有可選參數的函數呢?很簡單,只需使用不同的參數集重載函數即可:
void kill() {
kill(self);
}
void kill(Person person) {
person.setDeathTime(now());
}
順便說一下,由于這兩個缺點在單個類的范圍內并不明顯,因此在處理私有方法時可以放棄該規則。只要確保事物從外面是安全的即可。
4.驗證公共API參數
您和您的團隊可能會使用不成功傳遞null的原理,但是當公開公共API時,您無法控制其用戶以及將其傳遞給函數的內容。因此,請務必檢查傳遞給公共API的參數的正確性。
如果您唯一關心的是參數的無效性,請考慮使用Objects類中的requireNonNull函數:
public Foo(Bar bar, Baz baz) {
this.bar = Objects.requireNonNull(bar, "bar must not be null");
this.baz = Objects.requireNonNull(baz, "baz must not be null");
}
5. Leverage Optional
在Java 8之前,通常會在缺少值的情況下將方法返回null。這天生就是容易出錯的,因為開發人員必須經常檢查文檔,或者如果缺少文檔,則返回可能的null的基礎源代碼。
自從JDK 8發布以來,我們有了Optional類,該類專門設計用于指示可能缺少返回值。開發人員調用以Optional作為返回值的方法時,必須顯式處理不存在該值的情況。
因此,在適用時,請使用Optional來包裝您的返回類型。
Optional<String> makingYouCheck() {
// stuff
}
makingYouCheck().orElseThrow(ScrewYouException::new);
6.返回空集合而不是空
我們已經知道null不是方法的最佳返回值,并且我們可以使用 Optional類來指示該值可能丟失。但是當我們談論集合時,情況有所不同。
由于集合可以包含任意數量的元素,因此它也可以包含…0個元素!在Collections類中甚至有特殊的emptyXxx方法返回此類集合。
因此,我們應該避免返回null或使用Optional使事情復雜化,并且在沒有值可填充時返回空集合。
List<String> findSomething() {
if (someCondition) {
return Collections.emptyList();
}
// stuff
}
7.可選字段
正如我已經說過的那樣,Optional旨在指示缺少的返回值。類字段是一種誘人的案例,它不是為設計而設計的,而且肯定不是必需的。通過封裝,您應該完全控制字段的值,包括null。另一方面,將字段設置為顯式可選可能會給您帶來奇怪的問題,例如:
- 您應該如何為此類字段編寫構造函數或設置方法?
- 即使在確定值存在的情況下,您也必須處理Optional。
- 自動映射器應如何處理這些字段?
因此,對字段使用直接引用,并仔細分析字段在任何給定點是否可以為空。如果您的班級得到了很好的封裝,那么這應該很容易。
8.對空使用異常
您可能會看到人們使用null的一種奇怪情況是例外情況。這是一種固有的容易出錯的做法,因為關鍵錯誤可以在系統的不同位置被忽略或重新出現,從而使調試變得很痛苦。因此,如果出現問題,請始終拋出異常,而不是返回null。
9.測試您的代碼
此建議與各種錯誤有關,不僅是意外的null,而且它是如此重要,以至于我認為應該將其列入清單。使用類似于生產環境的環境徹底測試代碼是防止NPE的好方法。切勿在未確保其正常工作的情況下發布一段代碼。沒有所謂的“不需要測試的快速,簡單的修復程序”。
10.仔細檢查
每當您假設某個引用不能為空時,請仔細檢查您是否正確。在處理龐大的舊數據庫或外部提供程序時,這一點尤其重要。對于前者,請花一些時間檢查您要使用的列是否不包含任何空值,如果包含,則檢查這些行是否可以將其放入您的系統中。
如果是外部提供商,則依賴合同,文檔,如果不確定,請發送電子郵件或致電某人以確保您的假設正確。這可能很煩人,尤其是在使用文檔記錄不完善的API時,但涉及到null:安全勝過抱歉!
好啦!今天的分享到這里就結束了,希望大家持續關注馬哥教育!
文章來源于網絡,侵刪!