throwsキーワード
メソッドの中で例外が発生した場合、同じメソッドの中でキャッチせずに、メソッドの外へ投げることができる。
例外を送出する可能性のあるメソッドを作成する場合、メソッドの宣言で次のようにthrowsキーワードを使う。
戻り値 メソッド名(引数) throws 例外オブジェクトの型 {
例外を投げる可能性のあるメソッドの内容
}
例外処理をメソッドの中で行わず、呼び出し元で対処してほしいときに使用する。
throwとの違い
・throwは、例外を意図的に発生させて、例外処理を実行させることができる。
・throwsは、メソッド内で例外が発生した場合、自身のメソッド内でcatchするのではなく呼び出し元に例外を投げる。(呼び出し元でtry-catch文の準備をしておく必要があり)
例文
class InvalidAgeException extends Exception{
InvalidAgeException(String message){
super(message);
}
}
class Person{
int age;
void setAge(int age) throws InvalidAgeException{
if(age < 0){
throw new InvalidAgeException("年齢にマイナスの値が指定されました");
}
else{
System.out.println("年齢は" + age + "歳です");
}
}
}
public class ExceptionExample7{
public static void main(String[] args) {
Person p = new Person();
try{
p.setAge(-5);
}
catch(InvalidAgeException e){
System.out.println(e);
}
}
}
InvalidAgeException: 年齢にマイナスの値が指定されました
InvalidAgeExceptionクラス
例外オブジェクトのExceptionクラスを継承して独自の例外オブジェクトに宣言。
Personクラス
setAgeはメソッド年齢を設定するメソッドで引数で渡された値が負の数の場合(0未満の場合)、InvalidAgeExceptionオブジェクトを生成して例外を投げる。
メソッドの宜言にthrows InvalidAgeException と記述してあるのでこの例外を内部で処理せすに、呼び出し元に投げる。
この場合呼び出し元はtry-catch文を記述しているExceptionExample7クラスになる。
ExceptionExample7クラス
Personクラスのオブジェクトpを生成してtry文の中でsetAgeメソッドを呼び出している。
引数に負の値が設定されたのでPersonクラスの「void setAge(int age) throws InvalidAgeException」の記述で「throw new InvalidAgeException」の例外が呼び出し元にであるExceptionExample7クラス投げられてキャッチする。
「catch(InvalidAgeException e)」で例外をキャッチして例外の内容が出力される。
このようにすることで、意図しない値(マイナスの年齢)を設定しようとしたときにも、対応できるようになる。
スタックトレース
スタックトレースとは、実行中のコンピュータプログラムにエラーが発生した際に、直前に実行していた関数やメソッドなどの履歴を表示すること。
class SimpleClass{
void doSomething(){
int array[] = new int[3];
array[10] = 99;
System.out.println("doSomethingメソッド終了");
}
}
public class ExcepentionExample5{
public static void main(String[]args){
SimpleClass obj = new SimpleClass();
try{
obj.doSomething();
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println("例外をキャッチしました");
e.printStackTrace();
}
}
}
例外をキャッチしました
java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 3
at SimpleClass.doSomething(ExcepentionExample5.java:4)
at ExcepentionExample5.main(ExcepentionExample5.java:13)
上記のプログラムではSimpleClassクラスのdoSomethingメソッドの中で、配列のインデックスが範囲を超えて使用されているので例外が投げらているがメソッド内部にはtry-catch文がない。
しかしExceptionExample5クラスでSimpleClassクラスのmainメソッド内でオブジェクトobjを生成してtry - catch文を記述しているので例外が投げられキャッチしている。
catchブロックの「ArrayIndexOutOfBoundsException」は配列のインデックスとして存在しない要素を指定した場合にエラー通知をする例外オブジェクトでprintStackTraceメソッドは「スタックトレース」を出力する。引数eにはエラー内容の分が代入される。
e.printStackTrace();とする事で1行目にはエラー内容の分が、2行目の"at"以降には、どこでエラーが発生したか、3行目以降も"at"が続き、どこでエラーが発生したのかが表示される。2行目は実際にエラーが発生した場所だが、3行目以降はエラーが発生したメソッドを呼び出した場所が表示される。
参考記事