Javaでは、どちらを強くお勧めしますか。また、その理由は何ですか。どちらのタイプも例外をスローするので、その点でそれらの処理は同じです。 assert
は少し短いですが、それがどれほど重要かはわかりません。
public void doStuff(Object obj) {
assert obj != null;
...
}
対
public void doStuff(Object obj) {
if (obj == null) {
throw new IllegalArgumentException("object was null");
}
...
}
注意!
Assertions は、コードのコンパイル時に「アサーションを有効にする」ことを明示的に指定しない限り、実行時に削除されます。 Javaアサーションはプロダクションコードでは使用せず、プライベートメソッドに限定する必要があります( Exception vs Assertion を参照)。プライベートメソッドは既知であり、開発者のみが使用することが想定されています。また、assert
は AssertionError をスローします。これはError
ではなくException
を拡張し、通常は非常に異常なエラー( "OutOfMemoryError"など)があることを示します回復するのは難しいですよね?)あなたは治療することができるとは期待されていません。
「アサーションを有効にする」フラグを削除し、デバッガーで確認すると、IllegalArgumentExceptionスロー呼び出しを踏まないことがわかります...このコードはコンパイルされていないため(ここでも、「ea」が削除されたとき)
Public/protectedメソッドには2番目の構成を使用することをお勧めします。1行のコードで実行する処理が必要な場合は、少なくとも1つの方法を知っています。私は個人的に Spring Framework のAssert
クラスを使用します。このクラスには、引数をチェックするためのいくつかのメソッドがあり、失敗すると "IllegalArgumentException"がスローされます。基本的に、あなたがすることは:
Assert.notNull(obj, "object was null");
...実際には、2番目の例で記述したのとまったく同じコードを実行します。 hasText
、hasLength
などの便利なメソッドがいくつかあります。
必要以上に多くのコードを書くのが好きではないので、書き込む行数を2行減らすと嬉しいです(2行> 1行):-)
例外を使用する必要があります。アサーションを使用すると、機能が誤用されます。
未チェックの例外はライブラリのsersのプログラミングエラーを検出するように設計されていますが、アサーションはyour ownロジックのエラーを検出するように設計されています。これらは混合してはならない個別の問題です。
たとえば、アサーション
assert myConnection.isConnected();
「このアサーションに至る各コードパスによってmyConnection
が確実に接続されることを知っています。上記のコードが有効な接続を取得できなかった場合、このポイントに到達する前に例外をスローするか、戻ります。」
一方、チェック
if (!myConnection.isConnected()) {
throw new IllegalArgumentException("connection is not established");
}
「接続を確立せずにライブラリを呼び出すのはプログラミングエラーです」という意味です。
null
を有効なパラメーター値として許可しない関数を作成している場合は、@Nonnull
注釈を署名に追加し、 Objects.requireNonNull
を使用して引数がnull
であるかどうかを確認し、そうである場合はNullPointerException
をスローします。 @Nonnull
アノテーションはドキュメント用であり、場合によってはコンパイル時に役立つ警告を提供します。 null
が実行時に渡されるのを妨げません。
void doStuff(@Nonnull Object obj) {
Objects.requireNonNull(obj, "obj must not be null");
// do stuff...
}
更新:@Nonnull
アノテーションはJava標準ライブラリの一部ではありません。代わりに、サードパーティのライブラリの競合する標準( (@ NotNull Javaアノテーションを使用する必要がありますか? を参照)。それは、それを使用するのが悪い考えであることを意味するのではなく、それは標準ではありません。
私は常にアサーションよりもIllegalArgumentExceptionをスローすることを好みます。
アサーションは、主にJUnitまたはその他のテストツールで使用され、テスト結果をチェック/アサートします。そのため、あなたのメソッドがテストメソッドであると他の開発者に誤った印象を与える可能性があります。
メソッドに不正または不適切な引数が渡されたの場合、IllegalArgumentExceptionをスローすることも意味があります。これは、Java開発者が後に続く例外処理規則との整合性が高くなります。
私はアサートをあまり使用していませんが、Lombock @NonNullでの一般的なアプローチ: https://projectlombok.org/features/NonNull
Lombokの実装:lombok.NonNullをインポートします。
public class NonNullExample extends Something {
private String name;
public NonNullExample(@NonNull Person person) {
super("Hello");
this.name = person.getName();
}
}
Javaバージョン:
import lombok.NonNull;
public class NonNullExample extends Something {
private String name;
public NonNullExample(@NonNull Person person) {
super("Hello");
if (person == null) {
throw new NullPointerException("person");
}
this.name = person.getName();
}
}
ロンボクは私がどこでも使用する本当に素晴らしいライブラリです
2番目のIMOは、より多くの情報を提供し、さらに拡張して(たとえば、例外クラスを拡張することにより)より有益になるため、わずかに優れています。また、理解しやすい負の比較を使用しません。