皆さんこんにちは。
Numata です。
今回は、throw句とthrows句の違いを紹介します!
テキスト等で最初に見たとき、
似ているしなんとなく同じものだろう
なんて感じで曖昧な認識のままスルーしていませんか?
実はこの二つは全く別の処理をします。
曖昧な認識のまま進むと後々痛い目を見ます。
これを機に別物という理解、そしてそれぞれどのような処理をするのか理解しましょう!
もくじ
sの有無で全く別の意味になります
throw と throws は一見同じに見えますが、全く違う働きをします。
両者の末尾に注目すると、s がついているものとついていないものがあります。
最初、参考書等で見たとき、この s を見落としていませんか?
s の有無はとても大事です。もし
同じような動きをするんだろうな。
よく見てないけど、きっと同じものなんだろな。
と思っている方がいたら、まずは両者は全く別のもの
という認識を持ってください!
そりゃそうですよね。
プログラミングの世界では
たった1文字でもコードが間違っているときはエラーになります。
新しい技術を吸収するときは一字一句にまで注目して正しく理解しましょう!
throw はメソッド内 throws はメソッド宣言で使います
両者に違いがあることがわかりました。
ではそれぞれどのように使い分けるのでしょうか。
まずは出現ポイントを押さえましょう。
throw句:メソッドの中
throws句:メソッド宣言(引数を記述する()の後)
この2点をハッキリ分けて覚えましょう!
今までぼんやりと同じものに見えていたものでも、
この2点を意識するだけで別物に見えるはずです!
出現する場所は決まっています!
2点を意識して正確に覚えましょう!
それではそれぞれの役割を詳しく説明していきます!
throw:強制的に指定された種類のExceptionを発生させます
以下プログラム例です。
throw句はメソッドの中で書かれていることが確認できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public class Dice{ //このメソッドを実行すると、1~6の値を返す(1~6以外の数字が発生したら、Exceptionを返す) public int dice() throws Exception{ Random ran = new Random(); int dice = ran.nextInt(6)+1; //もし1~6以外の数字が出たら、Exceptionを発生 if(dice > 6 || dice < 1) { throw new Exception(); //ココでExceptionを発生させている } return dice; } } |
このプログラムでは、diceメソッドを実行したときに、
1~6以外の数字が出てたら、Exceptionを発生させる仕組みになっています。
Exceptionを発生させるとはどういうことかというと、
エラーになるということです。
つまり、プログラムが止まってしまいます。
今回はExceptionを発生させていますが、Exceptionと書いている箇所を
ArrayIndexOutOfBoundsExceptionに変えると、その種類のエクセプションが発生します。
1 2 3 |
java.lang.ArrayIndexOutOfBoundsException at Dice.dice(Dice.java:15) at Example0813.main(Example0813.java:9) |
Exception の種類を指定することができます!
throw句は強制的にエクセプションを発生させることができます!
強制的にエクセプションを発生させるということは、
必ず対処を記述する必要があります。
・エクセプションが発生する箇所を try – catch で囲む
・throws句をメソッド宣言に記述する
上記2パターンのどちらかで、エクセプションが発生した場合の
対処を明記する必要があります!
throws:メソッドの呼び元にexceptionを返します
サイド例プログラムです。
注目してほしいのはメソッド宣言です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public class Dice{ //このメソッドを実行すると、1~6の値を返す(1~6以外の数字が発生したら、Exceptionを返す) public int dice() throws Exception{ Random ran = new Random(); int dice = ran.nextInt(6)+1; //もし1~6以外の数字が出たら、Exceptionを発生 if(dice > 6 || dice < 1) { throw new Exception(); //ココでExceptionを発生させている } return dice; } } |
メソッド宣言の後に、throws Exception と書かれています。
throws が記述されていると、
エクセプションが発生したとき、呼び元に指定のエクセプションを返します。
戻り値と同じイメージをしてください。
void 以外で戻り値が宣言されている場合、
メソッドを実行すると、何かしらの戻り値が呼び元に返ってきますよね。
throws句も同様にエクセプションを戻します。
エクセプションを対処する場所が変わるということです。
以下プログラム例で確認してみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public class Sample { public static void main(String[] args) { Dice dice = new Dice(); try { dice.dice(); //diceメソッドはExceptionを返す可能性があるためtry catchで括る } catch (Exception e) { //System.out.println("1~6以外の数字が出ました!"); e.setStackTrace(null); } } } |
これは先ほどのDiceクラスをインスタンス化し、diceメソッドを実行しているクラスです。
throws句は、メソッドの呼び元にエクセプションを返します。
すると、本来Diceクラスの11行目で発生しているはずのエクセプションが、
Sampleクラスで発生します。
確実に発生が予想されるエクセプションには、対処をする必要があります。
このようにthrows句が宣言されているメソッドの実行には、実行元にエクセプションが
返ってくる可能性があるため、呼び元では必ず
try – catch でメソッド実行箇所を囲む必要があります。
逆に、Diceクラスではthrow句を try – catch で囲む必要がありません。
エクセプションを呼び元に返して、対処を託しているのです。
throws は上司・部下の関係をイメージするとわかりやすいです。
上司(呼び元)は、部下(メソッド)に対して仕事の指示を出します。
もし、部下が仕事を失敗する可能性がわかっていたら(throws句があったら)
上司は部下の失敗の責任を取らなければいけません。(try-catdhで囲む)
しかし、部下は失敗する可能性を上司に伝えていない(throws句なし)と
自分で責任を取らなければなりません。(try-catdhで囲む)
throws句は発生する可能性のあるエクセプションに対して、
誰が責任を取るか決めることができるのです!
throw と throws は全く別のモノです!
今まで同じに見えてきたモノですが、全く別のモノということが
ご理解いただけたと思います。
それぞれ全く別のものと理解して、
エクセプション対策をしましょう!
最後までご覧いただき、ありがとうございました。
コメント