2012-04-05 94 views
2

全部。我正在讀一本書,在寫一個方法時,其中一個想法是「不要返回null」。他建議當函數必須返回null時,「拋出異常」或「使用特殊情況」。不返回null - 返回什麼搜索功能

如果方法返回類型是一個列表,我知道我可以返回一個空列表而不是null。但是,如果返回類型是特定對象呢?例如,一種通過唯一ID搜索數據庫並返回結果的方法。如果方法找不到任何東西,我應該返回什麼?

我試圖使用「拋出異常」,但最終爲任何地方寫入更多的編碼和附加邏輯來調用函數。

任何建議將受到讚賞。

+0

的[玩轉Java的try/catch語句,並保持清潔的代碼,而無需返回一個空]可能重複(http://stackoverflow.com/問題/ 9775471/get-around-javas-try-catch-and-keep-the-code-clean-without-returning-a-null) – 2012-04-05 21:56:02

+0

這本書叫什麼名字? – hithwen 2013-10-14 15:53:09

+0

這是調用「乾淨的代碼」,但我想stackoverflow不喜歡名稱上顯示的帖子,所以有人刪除它 – 2013-10-16 05:37:21

回答

1

拋出異常是昂貴的操作,因爲有上下文切換和大量的調試信息被收集,所以你要避免將它們作爲控制流程流程的一種方式(特別是如果您可以處理這種情況而不會拋出異常)。返回null可以完全接受,以避免捕捉異常。

這個實例的一個例子是C#中的一對LINQ functions。這些方法可以返回空值:

SingleOrDefault(); // returns a single instance of an object, or null if not found 

FirstOrDefault(); // returns the first matching object, or null if not found 

這允許您檢查null而不嘗試通過異常處理找出控制流。

我能想到的一個例外(赦免雙關語)是使用異常來跨越程序邊界進行通信。例如,如果您的數據訪問層位於單獨的DLL中,並且您需要將數據庫故障傳遞迴父程序,則有時最好的方法是通過異常處理。

3

如果你不想返回null,那麼你可以使用類似Optional類。

+1

可選的好處是什麼。從我的角度來看,它僅將(obj == null)更改爲(可選 .absent()) – 2012-04-06 16:45:38

+1

它爲代碼提供了一些額外的類型安全性 - null在其意圖中更模糊,並且可能導致細微的錯誤客戶端不能正確處理它。番石榴的動機是:http://code.google.com/p/guava-libraries/wiki/UsingAndAvoidingNullExplained – fgb 2012-04-06 17:11:10

1

空被定義爲不存在,它似乎完全符合你想要的。如果你的代碼沒有返回任何東西,對吧?

但是,一如既往,這取決於。

如果你的代碼不是不返回任何內容,那麼這樣做可能會導致難以解決的問題。在這種情況下,拋出異常肯定更好。 1/null,無處不在。

如果不存在是一個完全有效的返回值,那麼爲什麼你想要返回一個異常呢?假設你已經有了代碼來處理從你的查詢中返回的不存在的值,那麼根本不需要拋出異常。

+0

同意。就我而言,該方法可能找不到任何東西,因此null無意義。但人們一直在談論「方法不應該返回null」。我很難真正實現這樣的想法 – 2012-04-06 16:47:47

0

我沒有看到任何問題返回null,但拋出異常似乎是最明智的選擇。你最好的選擇是創建你自己的自定義Exception類。

代碼應該差不多相同的兩種方式:

try { 
    SearchResult someResult = searchForStuff(); 
} 
catch (ResultNotFoundException rnfe) { 
    /* do stuff */ 
} 


/* almost the same as this */ 

SearchResult someResult = searchForStuff(); 

if (someResult == null) { 
    /* do stuff */ 
} 
1

如果Null可能是您可能返回的可能值,那麼如果找不到任何東西,則不應返回Null。例如,在:

[1, 2, 3, Null, 5].find(nonInteger) -> Null 
[1, 2, 3, 4].find(nonInteger) -> Null 

.find函數不能返回Null來表示失敗,因爲有時它會成功返回Null!相反,你可以改變的語義,或使用特殊的對象:

# changed semantics (with extra information returned) 
[1, 2, 3, Null, 5].find(nonInteger) -> index=4, value=Null 
[1, 2, 3, 4].find(nonInteger) -> index=Null, value=Null 

# changed semantics (with wrapper) 
[1, 2, 3, Null, 5].find(nonInteger) -> new Maybe(Null) 
[1, 2, 3, 4].find(nonInteger) -> new Maybe() 

# special object 
NoResultFound = new object() 
[1, 2, 3, Null, 5].find(nonInteger) -> Null 
[1, 2, 3, 4].find(nonInteger) -> NoResultFound