Murayama blog.

AIの民主化。

IllegalArgumentException IllegalStateExceptionの使い方

IllegalArgumentException IllegalStateExceptionの使い方についてまとめます。

IllegalArgumentException パラメータ値が不適切

メソッドのパラメータ(引数)が不正だった場合にスローする例外クラスです。
例えば、

	public void introdue(String address){

みたいなメソッドがあるとします。
さらに引数addressの仕様として「文字列桁数は16桁まで」と決まっている場合、以下のようにコーディングします。

	public void introdue(String address){
		if(address.length() > 16){
			throw new IllegalArgumentException("addressが16桁を超えています。");
		}
                // 処理
	}
引数がnullの場合

上記のintroduceメソッドの引数addressがnullの場合、慣例としてはNullPointerExceptionを利用します。
同様に、引数に配列などを扱う場合、インデックスが対象外となる場合はIndexOutOfBoundsExceptionを利用します。

IllegalStateException メソッドの呼び出しに対してオブジェクト状態が不正

オブジェクト自身の状態(フィールド)が適切でない場合にスローする例外です。
少し雑なサンプルですが、以下のプログラムを考えてみます。

public class Person {
	private String name;
	public void setName(String name) {
		this.name = name;
	}

	public void introdue(String address){
                // 引数のチェック
		if(address == null){
			throw new NullPointerException("addressがnullです。");
		}
		if(address.length() > 16){
			throw new IllegalArgumentException("addressが16桁を超えています。");
		}
		System.out.printf("私の名前は%sです。住所は%sです。", name, address);
	}
}

上記のPersonクラスにはintroduce(挨拶をする)というメソッドがあります。
introduceメソッドはフィールドのnameと引数のaddressを出力します。
このintroduceメソッドは呼び出されたとき、引数addressは正しくチェックされていますが、フィールドnameが正しく設定されていない可能性があります。
ここでは、仕様としてフィールドnameは8桁を超える場合を状態が不正であるとみなし、例外をスローするものとします。
状態(フィールド)が不正である場合は、IllegalStateExceptionをスローします。

	public void introdue(String address){
		// 引数のチェック
		if(address == null){
			throw new NullPointerException("addressがnullです。");
		}
		if(address.length() > 16){
			throw new IllegalArgumentException("addressが16桁を超えています。");
		}
		
		// 状態のチェック
		if(name == null){
			throw new NullPointerException("nameが正しく初期化されていません。");
		}
		if(name.length() > 8){
			throw new IllegalStateException("nameが8桁を超えています。");
		}

		System.out.printf("私の名前は%sです。住所は%sです。", name, address);
	}

上記のプログラムでは、

		// 状態のチェック
		if(name == null){
			throw new NullPointerException("nameが正しく初期化されていません。");
		}
		if(name.length() > 8){
			throw new IllegalStateException("nameが8桁を超えています。");
		}

の部分が状態のチェックになります。
メソッド呼び出し時に、オブジェクトの状態が不正である場合はIllegalStateExceptionをスローします。
ただし、引数がnullの場合と同様、オブジェクトの状態がnullである場合はNullPointerExceptionを返すのが慣例です。

まとめ

オブジェクトのメソッド呼び出しの際にチェックすべき例外は以下の2点。

例外クラス 意味
IllegalArgumentException パラメータ値が不適切
IllegalStateException メソッドの呼び出しに対してオブジェクト状態が不正

慣例としては、NullPointerExceptionやIndexOutOfBoundsExceptionが使える場合はそれらに置き換える。


ちなみに、ここでまとめた内容はpublicメソッドに対する例外の扱い方です。
privateメソッドなどの外部に公開しないメソッドについてはまた話は別です。
#例えば、privateメソッドは、呼び出しもとをクラス内に制限(把握)できるため、ここまで厳密なチェックは必要でありません。



Effective Java 第2版 (The Java Series)

Effective Java 第2版 (The Java Series)