今天,我將向您展示如何在應用程式中避免 NullPointerException 的簡單技術。它們很容易遵循,但可以顯著提高程式碼的可靠性和品質。此外,根據我的經驗,第一個技巧將對程式碼的品質產生顯著的影響。如果您知道任何其他 Java 程式設計技巧,請隨時在評論中分享。
使用
有許多開源函式庫承擔測試盡量不要
這是 Joshua Bloch 在他的《Java:有效程式設計》一書中描述的另一個很好的 Java 程式設計技巧。傳回空集合或陣列時,請確保呼叫
對已知字串文字而不是未知物件呼叫 equals() 和 equalsIgnoreCase() 方法
equals()
始終對您知道不是的已知字串呼叫方法null
。此方法equals()
是對稱的,即調用a.equals(b)
和b.equals(a)
會給出相同的結果(ifa
和b
not null
),因此許多程式設計師不注意調用equals()
、 ya
或 y哪個物件b
。如果在 上呼叫該方法,其副作用之一是 NullPointerException null
。
Object unknownObject = null;
//плохой способ - может вызвать NullPointerException
if(unknownObject.equals("knownObject")){
System.err.println("This may result in NullPointerException if unknownObject is null");
}
//правильный способ - исключение NullPointerException не возникнет, даже если unknownObject null
if("knownObject".equals(unknownObject)){
System.err.println("better coding avoided NullPointerException");
}
這是避免 NullPointerException 的最簡單技巧,但它本身就帶來了巨大的改進,因為方法equals()
隨處可見。
如果兩者產生相同的結果,請選擇 valueOf() 而不是 toString()
由於調用toString()
帶有值的參考null
會引發 NullPointerException,因此最好valueOf()
在可以獲得相同結果時使用調用,因為調用valueOf()
from null
returns null
。Integer
對於諸如、或 之類Float
的包裝類尤其如此。 Double
BigDecimal
BigDecimal bd = getPrice();
System.out.println(String.valueOf(bd)); //не выбрасывает NPE
System.out.println(bd.toString()); //выбрасывает "Exception in thread "main" java.lang.NullPointerException"
當您不確定某個物件是否存在時,請使用這些提示null
。
使用null
安全的方法和函式庫
有許多開源函式庫承擔測試null
. 最常見的之一StringUtils
來自 Apache Commons。使用諸如StringUtils.isBlank()
、isNumeric()
等方法isWhiteSpace()
。您不必擔心拋出 NullPointerException。
//Методы StringUtils являются null-безопасными, они не вызовут NullPointerException
System.out.println(StringUtils.isEmpty(null));
System.out.println(StringUtils.isBlank(null));
System.out.println(StringUtils.isNumeric(null));
System.out.println(StringUtils.isAllUpperCase(null));
輸出: true true false false 然而,在使用之前,不要忘記閱讀null
安全方法和類別的文檔。這是另一個最好的 Java 技巧,不需要太多努力就能帶來巨大的改進。
盡量不要null
從方法中返回,最好返回一個空集合
這是 Joshua Bloch 在他的《Java:有效程式設計》一書中描述的另一個很好的 Java 程式設計技巧。傳回空集合或陣列時,請確保呼叫size()
或等基本方法length()
不會引發 NullPointerException。該類別Collections
專門聲明了空列表、集合和字典的便捷實作:Collections.EMPTY_LIST
、Collections.EMPTY_SET
和Collections.EMPTY_MAP
。例如:
public List getOrders(Customer customer){
List result = Collections.EMPTY_LIST;
return result;
}
同樣,您可以使用Collections.EMPTY_SET
它Collections.EMPTY_MAP
而不是返回null
。
使用@NotNull和@Nullable註釋
在方法的描述中,您可以null
使用註解@NotNull
和 @Nullable 來定義方法安全約定,以指示方法是否可以傳回null
。現代編譯器和 IDE 可以使用這些註解來分析您的程式碼並提供適當的建議,例如,關於缺少對 的檢查的建議,反之亦然null
,關於是否可能刪除阻塞程式碼的不必要的檢查。例如,此類註釋受到 IntelliJ IDE 和 FindBugs 的支持,並且它們也包含在 JSR 305 中。但即使您的 IDE 不支援此類註釋,它們本身也將是很好的文件。程式設計師可以更輕鬆地了解在哪裡添加檢查@NotNull
以及在哪裡不添加檢查。順便說一句,這對 Java 程式設計師來說是一種相當新的做法,它的傳播需要時間。 @Nullable
null
避免程式碼中不必要的自動裝箱和自動拆箱
這不僅會導致創建不必要的臨時對象,而且如果包裝類別是null
. 例如,如果 person 條目不包含電話號碼並傳回 ,以下程式碼將引發 NullPointerException null
。
Person ram = new Person("ram");
int phone = ram.getPhone();
使用自動裝箱或自動拆箱時,不僅是等式,而且不等式<
>都>
可能導致 NullPointerException。
遵循約定並定義合理的預設值。
在 Java 中避免 NullPointerException 的最佳方法之一是正確聲明並遵循編碼約定。大多數 NullPointerException 發生在您嘗試建立物件但沒有它所需的所有資料和依賴項時。透過優雅地拒絕此類請求來防止建立未完成的對象,您將避免將來出現大量 NullPointerException。同樣,如果允許建立對象,則應該選擇合理的預設值。例如,Employee
如果沒有名稱和 ,則無法建立類別對象id
,但可能沒有電話號碼。在這種情況下,Employee
沒有數字的物件可能會傳回零null
。儘管應該提前考慮對象的這種行為,但檢查可能比null
撥打不存在的號碼更容易。在這種情況下,對哪些欄位是null
、哪些不是欄位有額外的條件將有助於做出正確的決定。一般來說,選擇立即崩潰程序還是分配null
程序是一個重要的設計決策,一旦做出選擇,就必須始終如一地遵循它。
在 DBMS 層級設定限制
當使用資料庫儲存程序物件(例如客戶或訂單)時,明智的做法是null
使用適當的表格限制在 DBMS 層級指定物件的「性質」。資料庫通常包含來自多個來源的信息,引入缺失值檢查將提高資料的完整性。此外,在 DBMS 層級對 null 檢查的存在將減少 Java 程式碼中的空值:透過將資料庫中的資料載入到 Java 物件中,您可以確定它們的存在並從程式碼中刪除不必要的「!= null
」。
使用空物件模式
建立特殊Null
物件是避免 Java 中 NullPointerExcpetion 的另一種方法。假設應用程式中的某些方法傳回一個對象,程式隨後透過呼叫其方法來使用該對象。例如,該方法傳回用於迭代集合的Collection.iterator()
類別的物件。Iterator
然後,如果原始對象沒有任何迭代器,null
您可以返回一個特殊的- 對象,該對象具有始終返回 的Null
方法。親愛的讀者,這就是我關於消除 Java 程式 NullPointerException 錯誤的技巧的結束。您將體會到這些簡單且不繁瑣的規則是多麼有用。提醒一下,如果您想分享 Java 程式中的任何其他 NullPointerException 技巧,請隨時在評論中進行。 專門為 JavaRush 學生翻譯。原來的hasNext()
false
GO TO FULL VERSION