IllegalArgumentExceptionの原因と対策方法はとても簡単です。
基本的なことを理解すればすぐに解消できます。
IllegalArgumentExceptionとは?
不正な引数または不適切な引数をメソッドに渡したことを示すためにスローされる例外です。
例えば、0以上の値が渡されるべきなのに、負数が渡されるとスローされるといったものです。
原因
具体的なコードで発生原因を確認していきましょう。
■発生させるコード
例としてFileクラスのsetLastModifiedメソッドに「-1」をセットします。
1 2 3 4 5 6 7 8 9 10 |
package IllegalArgumentException; import java.io.File; public class Main { public static void main(String[] args) { File file = new File("dummy"); file.setLastModified(-1); // ← ★発生箇所 } } |
■実行結果
そうすると、IllegalArgumentExceptionが発生します。
1 2 3 |
Exception in thread "main" java.lang.IllegalArgumentException: Negative time at java.base/java.io.File.setLastModified(File.java:1439) // ← ★原因 at IllegalArgumentException.Main.main(Main.java:8) // ← ★発生箇所 |
■原因
原因は、setLastModifiedメソッドでは0より小さい数値に対してIllegalArgumentExceptionを発生させるようにしていたからです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public class File implements Serializable, Comparable<File> { ・・・ public boolean setLastModified(long time) { if (time < 0) throw new IllegalArgumentException("Negative time"); // ← ★原因 SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkWrite(path); } if (isInvalid()) { return false; } return fs.setLastModifiedTime(this, time); } |
解消方法
IllegalArgumentExceptiongが発生しない条件の値をメソッドに渡してあげることです。
上記の例だと、setLastModifiedTimeメソッドに0以上の値を渡せば問題ありません。
IllegalArgumentExceptiongが発生した場合、発生箇所はスタックトレース(■実行結果のような出力)で確認できますし、発生箇所も書いてあるので追うことは簡単です。
発生条件も書いてあるので、不適切な値が入らないようにしてあげればよいだけですね。
IllegalArgumentExceptionの使い方
独自のクラスを作って、その中でIllegalArgumentExceptionを発生させたいときは以下のようにします。
■使い方の例
例外発生時のメッセージ有無と、原因となる例外を渡すか否かを組み合わせた4パターンがあります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
package IllegalArgumentException; public class MyClass { private Integer value; private String name; private String code; private Integer number; // 詳細メッセージ無しの場合 public void setValue(Integer value) { if (name == null) { throw new IllegalArgumentException(); } this.name = name; } /** Exception in thread "main" java.lang.IllegalArgumentException at IllegalArgumentException.MyClass.setValue(MyClass.java:12) at IllegalArgumentException.MyClassUse.main(MyClassUse.java:6) */ // 詳細メッセージありの場合 public void setName(String name) { if (name == null) { throw new IllegalArgumentException("Can't set null."); } this.name = name; } /** [エラーメッセージを挿入した関係で、以降は行数の表記がずれています] Exception in thread "main" java.lang.IllegalArgumentException: Can't set null. at IllegalArgumentException.MyClass.setName(MyClass.java:20) at IllegalArgumentException.MyClassUse.main(MyClassUse.java:7) */ // 詳細メッセージなしで、原因となる新規例外を設定する public void setCode(String code) { if (code == null) { throw new IllegalArgumentException(new RuntimeException("code is null.")); } this.code = code; } /** Exception in thread "main" java.lang.IllegalArgumentException: java.lang.RuntimeException: code is null. at IllegalArgumentException.MyClass.setCode(MyClass.java:28) at IllegalArgumentException.MyClassUse.main(MyClassUse.java:8) Caused by: java.lang.RuntimeException: code is null. ... 2 more */ // 詳細メッセージありで、原因となる新規例外を設定する public void setNumber(Integer number) { if (number == null) { throw new IllegalArgumentException("Can't set null.", new RuntimeException("number is null.")); } this.number = number; } /** Exception in thread "main" java.lang.IllegalArgumentException: Can't set null. at IllegalArgumentException.MyClass.setNumber(MyClass.java:36) at IllegalArgumentException.MyClassUse.main(MyClassUse.java:9) Caused by: java.lang.RuntimeException: number is null. ... 2 more */ } |
基本的にはIllegalArgumentExceptionにメッセージを付けるだけのパターンが多いと個人的には認識しています。
発生原因となっている詳細が必要な場合には、上記の例のように新規例外を設定してあげるとよいので必要に応じて使い分けるようにして下さい。
まとめ
- IllegalArgumentExceptionとは不正な引数または不適切な引数をメソッドに渡したことを示すためにスローされる例外
- 原因はメソッドに不正な値が入ったことによるもの
- 解消方法は発生箇所から追って行き、適切な値を確認して、渡される値を制御する
- 独自クラスで例外をスローすることは可能
また、スロー時はメッセージ有無と原因となる新規例外の設定有無を選択できる
参考
例外はJava Silver SE 11でも取り扱う範囲となっています。
処理方法をしっかり理解して資格の取得にも挑戦してみて下さい!
コメント