このページではJavaの例外処理として、throwとthrowsについてご紹介しよう。
とても似ているが、それぞれで意味も使い方も違う。
例外処理を行う上で、どちらも知っておこう。
throwとthrows
Javaの例外処理には「throw」、「throws」という処理がある。両方ともその名前の通り処理を「投げる」という意味だ。
名前は同じような「throw」、「throws」であるが、内容はだいぶ違う。それぞれの特徴をよく理解して利用していきたい処理だ。
throw
まずは「throw」についてみてみよう。「throw」は例外を意図的に起こして、例外処理を行わせることができる。
例外を意図的に発生させるメリットとしては、以下サンプルプログラムのように、引数の値が望んでいるものでない場合に例外を発生させ、呼び出し元にエラーメッセージを返すことができるなどがある。
サンプルプログラムで処理を確認してみよう。
1 2 3 4 5 |
void testA (int num) { //・・・① if(num == 0) { //・・・② throw new IllegalArgumentException(“引数の値が不正です”); //・・・③ } } |
①のメソッドtestAでは引数に「num」という数値型を指定している。
②のif文は引数の「num」が0だった場合に特定の処理を行おうとしている。
③の「IllegalArgumentException」は不正な引数、または不適切な引数をメソッドに渡したことを示すための例外だ。このようにthrowを使うことで、プログラマが例外を意図的に呼び出すことができる。使用方法は下記のように「throw new 例外用クラス」のように書く。
throw new IllegalArgumentException(“引数の値が不正です”);
throws
名前は「throw」と似ているが処理内容は全く異なる「throws」についてみてみよう。
throwsはメソッド内で例外が発生した場合、自信のメソッド内でcatchするのではなく、呼ばれる側に例外を投げる処理だ。
例外処理はtry catch文を書くか、throwsで呼び出し元に例外を投げるという二つの方法がある。(※throwsが書かれたメソッドを呼び出す場合はtry catch文が必要になる。)
1 2 3 4 5 6 7 8 9 10 11 |
void testB () throws FileNotFoundException { //・・・① FileReader r = new FileReader(“sample.txt”); //・・・② System.out.print(“ファイルを読み込みました”); } void testC () { //・・・③ try { testB(); //・・・④ } catch (FileNotFoundException e) { //・・・⑤ System.out.print(“ファイルが存在しませんでした”); //・・・⑥ } } |
①の下記1文でメソッド内で起こりうる例外を指定して、その例外を呼び出し元に投げる。例外は複数設定することも可能だ。上記のサンプルプログラムはファイルを読み込む処理であるため、「FileNotFoundException」を指定している。
throws FileNotFoundException
②で「sample.txt」というファイルを読み込む処理を行っているが、「sample.txt」ファイルが存在しない場合「FileNotFoundException」例外が発生する。
次に③の「testC」メソッドをみてみよう。testCメソッド内ではtry catch文が書かれており、例外をcatchできるようになっている。
④でファイルを読み込むtestBメソッドを呼び出している。ここで呼び出したtestBメソッドで例外が発生した場合、例外がtestBメソッドからtestCメソッドに投げられるため、⑤でcatchされ、⑥の「ファイルが存在しませんでした」が出力される。
サンプルプログラムのtestCメソッドを実行した場合は、以下のような実行結果が考えられる。
「sample.txt」ファイルが存在しなかった場合
「ファイルが存在しませんでした」が出力される。
「sample.txt」ファイルが存在した場合
「ファイルを読み込みました」が出力される。
まとめ
このページではJavaのthrowとthrowsについてご紹介した。どちらもJavaプログラミングをしていく上で、必ず使うものだ。
理解して、マスターしてしまおう。
throwで結局なにか、どこに、どのように返されるのかが理解できずにいます。
コンソールに「引数の値が不正です」が出力されるということでしょうか…?
また、どういった際に利用するのかも、メリットの観点から察することができませんでした。
ご愛読ありがとうございます。
ざっくりとですが「throwはメソッドの内側で使う」「throwsはメソッドを呼び出す時に使う」と考えると簡単かもしれません。
throwのサンプルではメソッド内で「もし数値が0だったら××する」という処理を行っています。メソッドの中だけで処理が完結しています。
throwsはメソッド間の通信に使われています。サンプルを見ますとtestBとtestCという2つのメソッドがあり
testBは「ファイルが見つからない可能性(FileNotFoundException)があるのを前提にファイルを読み込む役割のメソッド」
testCは「testBにファイルの読み込みを依頼し、その結果に応じてメッセージの処理を行うメソッド」と役割が分かれています。
(1) testCはまず「目的のファイルがあるかないかわからない状況」でtestBの実行を行います(try)
(2) testBはその要請を受けてファイルを読み込みし、成功すればメッセージを出し、失敗すれば例外を返します(ここでthrowsが効果を発揮する)
(3) ファイルが見つからない等の理由でtestBより例外が返ってきたら(catch)testCがメッセージを出します