![](/img/trans.png)
[英]Is it proper to mark a param as @Nullable and then throw an IllegalArgumentException when a null is passed in?
[英]Automatically throwing IllegalArgumentException when null values are passed to a method
我正在探索在重構我正在研究的代碼庫的一部分時消除null的可能性。 我們已升級到java 8,因此我們可以使用Optional<T>
。 為了有效地執行此操作,我們需要確保不將null傳遞給任何方法(這是在我們將Optional
中的任何潛在空值包裝在從外部服務/庫進入我們的系統之后)。 處理此問題的顯而易見的方法是顯式檢查null並在必要時拋出IllegalArgumentException
,但是,這將是不合理的冗長和手動。 是否有更少的手動/更簡潔的方式來做到這一點?
你可以使用Objects::requireNonNull
。 例如,在構造函數中,您可以執行以下操作:
this.myField = Objects.requireNonNull(myField);
如果傳遞null
,它將拋出NullPointerException
。
避免過度使用Optional
。 例如,請參閱此答案 。
您可以嘗試使用@NonNull注釋的Lombok注釋處理器。 使用NonNull注釋參數將在編譯期間自動生成空值檢查,因此您將在運行時獲得NullPointerException
或IllegalArgumentException
(無論您喜歡哪個)。
我將使用以下方法,該方法結合使用@Nonnull
注釋(靜態分析)和通過Guava的前提條件進行顯式的,快速失敗的運行時檢查:
import javax.annotation.Nonnull;
import static com.google.common.base.Preconditions.checkNotNull;
public void doSomething(@Nonnull MyClass input) {
checkNotNull(input);
/* Do something */
}
@Nonnull
注釋使兼容的IDE或靜態分析工具(如FindBugs)能夠標記明顯違反合同的客戶端代碼。 作為額外的一層防御, checkNotNull
保證如果由於某種原因傳入了null
輸入,則該方法會在NullPointerException
情況下提前和大聲退出。
將有其他答案提出消除檢查代碼的方法。 這些方式往往像魔法一樣工作,我並不特別喜歡魔法。 因此,我將向您提出一種不完全消除冗長和手動打字的方法,但將其減少到一半 。
java中的斷言如下所示:
assert n != null;
如您所見,它占用一行而不是兩行,並且如果您對它拋出的AssertionError
異常感到滿意,則它不需要手動編寫throw
語句。 一般情況下,我們不趕指示的錯誤,所以在大多數情況下,你應該罰款例外,但如果你必須真的有一個IllegalArgumentException
,那么你可以按如下編寫你的斷言語句:
assert n != null : new IllegalArgumentException( "n cannot be null" );
如果n
為null
,那么將會拋出一個新的AssertionError
異常,並且此異常的“原因”將是您的IllegalArgumentException
。 因此, IllegalArgumentException
將出現在堆棧跟蹤中,盡管在“由...引起”行之后。
作為一個額外的好處,一旦你有一個通過所有測試並且你知道它有效的系統,你就-enableassertions
提供-enableassertions
(簡稱-ea
)VM選項,並且你的程序運行得會稍微快一些,因為斷言會不予評估。
Checker框架提供了一個注釋@NonNull
,允許編譯時檢查是否存在可以將空值傳遞給帶注釋的引用的代碼路徑。
請參閱: https : //checkerframework.org/api/org/checkerframework/checker/nullness/qual/NonNull.html
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.