グアバの事前条件のガイド
1. 概要
このチュートリアルでは、Google GuavaのPreconditionsクラスの使用方法を示します。
Preconditionsクラスは、メソッドまたはコンストラクターが有効なパラメーター値で呼び出されたことを確認するための静的メソッドのリストを提供します。 前提条件が失敗すると、調整された例外がスローされます。
2. Google GuavaのPreconditions
Preconditionsクラスの各静的メソッドには、次の3つのバリアントがあります。
-
引数なし。 エラーメッセージなしで例外がスローされます
-
エラーメッセージとして機能する追加のObject引数。 エラーメッセージとともに例外がスローされます
-
追加のString引数。任意の数の追加のObject引数が、プレースホルダー付きのエラーメッセージとして機能します。 これはprintfのように動作しますが、GWTの互換性と効率のために、%sインジケーターのみを許可します
Preconditionsクラスの使用方法を見てみましょう。
2.1. メーベン依存
pom.xmlにGoogleのGuavaライブラリの依存関係を追加することから始めましょう。
com.google.guava
guava
21.0
依存関係の最新バージョンはhereで確認できます。
3. checkArgument
Preconditions classのTheメソッドcheckArgumentは、呼び出し元のメソッドに渡されるパラメーターの真実性を保証します。 このメソッドはブール条件を受け入れ、条件がfalseの場合はIllegalArgumentExceptionをスローします。
この方法をいくつかの例で使用する方法を見てみましょう。
3.1. エラーメッセージなし
checkArgumentメソッドに追加のパラメーターを渡すことなく、checkArgumentを使用できます。
@Test
public void whenCheckArgumentEvaluatesFalse_throwsException() {
int age = -18;
assertThatThrownBy(() -> Preconditions.checkArgument(age > 0))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage(null).hasNoCause();
}
3.2. エラーメッセージ付き
エラーメッセージを渡すことにより、checkArgumentメソッドから意味のあるエラーメッセージを取得できます。
@Test
public void givenErrorMsg_whenCheckArgEvalsFalse_throwsException() {
int age = -18;
String message = "Age can't be zero or less than zero.";
assertThatThrownBy(() -> Preconditions.checkArgument(age > 0, message))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage(message).hasNoCause();
}
3.3. テンプレートエラーメッセージ付き
エラーメッセージを渡すことにより、checkArgumentメソッドから動的データとともに意味のあるエラーメッセージを取得できます。
@Test
public void givenTemplateMsg_whenCheckArgEvalsFalse_throwsException() {
int age = -18;
String message = "Age should be positive number, you supplied %s.";
assertThatThrownBy(
() -> Preconditions.checkArgument(age > 0, message, age))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage(message, age).hasNoCause();
}
4. checkElementIndex
メソッドcheckElementIndexは、インデックスがリスト、文字列、または指定されたサイズの配列内の有効なインデックスであることを確認します。 要素インデックスの範囲は、0から包括的0までです。 リスト、文字列、配列を直接渡すのではなく、サイズを渡すだけです。 このメソッドは、インデックスが有効な要素インデックスでない場合はIndexOutOfBoundsExceptionをスローし、そうでない場合はメソッドに渡されているインデックスを返します。
例外がスローされたときにエラーメッセージを渡して、checkElementIndexメソッドから意味のあるエラーメッセージを表示することにより、このメソッドをどのように使用できるかを見てみましょう。
@Test
public void givenArrayAndMsg_whenCheckElementEvalsFalse_throwsException() {
int[] numbers = { 1, 2, 3, 4, 5 };
String message = "Please check the bound of an array and retry";
assertThatThrownBy(() ->
Preconditions.checkElementIndex(6, numbers.length - 1, message))
.isInstanceOf(IndexOutOfBoundsException.class)
.hasMessageStartingWith(message).hasNoCause();
}
5. checkNotNull
メソッドcheckNotNullは、パラメーターとして指定された値がnullかどうかをチェックします。 チェックされた値を返します。 このメソッドに渡された値がnullの場合、NullPointerExceptionがスローされます。
次に、エラーメッセージを渡してcheckNotNullメソッドから意味のあるエラーメッセージを取得する方法を示すことにより、このメソッドの使用方法を示します。
@Test
public void givenNullString_whenCheckNotNullWithMessage_throwsException () {
String nullObject = null;
String message = "Please check the Object supplied, its null!";
assertThatThrownBy(() -> Preconditions.checkNotNull(nullObject, message))
.isInstanceOf(NullPointerException.class)
.hasMessage(message).hasNoCause();
}
エラーメッセージにパラメータを渡すことにより、checkNotNullメソッドからの動的データに基づいて意味のあるエラーメッセージを取得することもできます。
@Test
public void whenCheckNotNullWithTemplateMessage_throwsException() {
String nullObject = null;
String message = "Please check the Object supplied, its %s!";
assertThatThrownBy(
() -> Preconditions.checkNotNull(nullObject, message,
new Object[] { null }))
.isInstanceOf(NullPointerException.class)
.hasMessage(message, nullObject).hasNoCause();
}
6. checkPositionIndex
メソッドcheckPositionIndexは、このメソッドに引数として渡されたインデックスが、指定されたサイズのリスト、文字列、または配列内の有効なインデックスであることを確認します。 位置インデックスの範囲は、0からサイズまでです。 リスト、文字列、配列を直接渡すのではなく、サイズを渡すだけです。
このメソッドは、渡されたインデックスが0と指定されたサイズの間にない場合はIndexOutOfBoundsExceptionをスローし、そうでない場合はインデックス値を返します。
checkPositionIndexメソッドから意味のあるエラーメッセージを取得する方法を見てみましょう。
@Test
public void givenArrayAndMsg_whenCheckPositionEvalsFalse_throwsException() {
int[] numbers = { 1, 2, 3, 4, 5 };
String message = "Please check the bound of an array and retry";
assertThatThrownBy(
() -> Preconditions.checkPositionIndex(6, numbers.length - 1, message))
.isInstanceOf(IndexOutOfBoundsException.class)
.hasMessageStartingWith(message).hasNoCause();
}
7. checkState
メソッドcheckStateは、オブジェクトの状態の有効性をチェックし、メソッドの引数に依存しません。 たとえば、Iteratorはこれを使用して、removeを呼び出す前にnextが呼び出されたことを確認できます。 このメソッドは、オブジェクトの状態(メソッドに引数として渡されたブール値)が無効な状態の場合、IllegalStateExceptionをスローします。
例外がスローされたときにエラーメッセージを渡して、checkStateメソッドから意味のあるエラーメッセージを表示することにより、このメソッドをどのように使用できるかを見てみましょう。
@Test
public void givenStatesAndMsg_whenCheckStateEvalsFalse_throwsException() {
int[] validStates = { -1, 0, 1 };
int givenState = 10;
String message = "You have entered an invalid state";
assertThatThrownBy(
() -> Preconditions.checkState(
Arrays.binarySearch(validStates, givenState) > 0, message))
.isInstanceOf(IllegalStateException.class)
.hasMessageStartingWith(message).hasNoCause();
}
8. 結論
このチュートリアルでは、GuavaライブラリのPreConditionsクラスのメソッドを説明しました。 Preconditionsクラスは、メソッドまたはコンストラクターが有効なパラメーター値で呼び出されることを検証するために使用される静的メソッドのコレクションを提供します。
上記の例に属するコードはthe GitHub projectにあります。これはMavenベースのプロジェクトであるため、そのままインポートして実行するのは簡単です。