例外処理 (try , catch , finally)


今回は例外処理についてみていきます。

例外処理とは

プログラミングでは、プログラムがある処理を実行している途中で、なんらかの異常が発生することを例外という。Windowsでのブルースクリーンが表示される例外0Eなどがこれにあたる。例外が発生した場合に、現在の処理を中断(中止)して別の処理を行うことを例外処理という。簡単な例として、0での除算が起こる、存在しないファイルを読み書きしようとする、などの状況である。プログラミング言語としては、JavaやC++などが例外機構を備えている。

wikipedia参考・引用

構文などコードの記述にはエラーがなくコンパイルはできるが、実行途中で異常が発生する場合があります。このような異常が発生すると処理エラーになりプログラムが途中で止まってしまいます。このような異常処理が発生したときに単に強制中断して終わるのではなく、異常時の処理を記述しておいてその処理を実行させることを例外処理といいます。

言語サポート

例外が発生したことを見落として正常時の動作を継続してしまうと、より深刻・致命的な異常を招くおそれがある。それを避けるには例外が発生したことのチェックを綿密に行い、例外が検出された場合には適切な事後処理を行う他ない。しかし、大規模なプログラムではこのようなチェックは膨大なものとなり、本来目的としている正常時の処理よりも多くの記述を必要とする場合すらある。
そこで、Javaでは例外の発生チェックをほぼ自動化している。例外が発生すると現在の処理を中断する。発生した例外の事後処理を担当できるハンドラを探して次々にコールスタック(関数呼び出し)を遡り、適切なハンドラを見つけるとそれに事後処理を任せる。

wikipedia参考・引用

例外処理の構文

【例1】

public class Sample{
    public static void main(String[] args) {
        int[] array = {0,1,2};
        System.out.println(array[3]);
        System.out.println("last");
    }
}
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at Sample.main(Sample.java:4)

まずは例外処理の記述のないコードです。4行目で配列要素のインデックス3を参照しようとしていますが、この配列要素は存在しない為、異常エラーになり処理が強制中断しています。処理が中断しているので5行目の「last」を表示する処理は実行されません。

【例2】

public class Sample{
    public static void main(String[] args) {
        int[] array = {0,1,2};
        try{
            System.out.println(array[3]);
        }
        catch (Exception e){
            System.out.println("例外が発生しました。");
        }
        System.out.println("last");
    }
}
例外が発生しました。
last

例外処理を組み込んだコードです。例外処理は4~6行目のtryブロックと7~9行目のcatchブロックからなります。tryブロックで例外が発生すると、そこでtryブロックの処理は中断し、catchブロックの処理に移ります。

try{
    例外が発生しそうな処理
}
catch(例外クラスの型 引数名){
    例外処理
}

5行目で配列要素のインデックス3を参照しようとしていますが、この配列要素は存在しない為、異常エラーになります。しかし今回はtryブロック内である為、catchブロックの処理に移ります。そしてcatchブロックの処理後に10行目の「last」を表示する処理を行っています。つまり異常エラーが発生しても途中で強制中断されていません。このように例外処理をすることにより異常エラーによる強制終了を防ぐことができます。

複数例外処理

【例3】

public class Sample{
    public static void main(String[] args) {
        int[] array = {0,1,2};
        try{
            System.out.println(array[3]);
        }
        catch (ArithmeticException e){
            System.out.println("算術計算がおかしいです。");
        }
        catch (ArrayIndexOutOfBoundsException e){
            System.out.println("配列の要素が存在しません。");
        }
        System.out.println("last");
    }
}
配列の要素が存在しません。
last

catchブロックは複数作ることができます。例外が発生するとエラー情報を持つ例外オブジェクトが生成されcatchブロックに渡されます。catchブロックには「例外クラスの型を指定した引数」を指定できますが、発生した例外と指定した例外クラスが一致するcatchブロックが選択されます。

例3では2つのcatchブロックがあります。

  1. 算術計算で例外的条件が発生した場合にスローされるArithmeticExceptionクラス
  2. 不正なインデックスを使って配列がアクセスされたことを示すためにスローされるArrayIndexOutOfBoundsExceptionクラス

5行目で配列要素のインデックス3を参照しようとしていますが、この配列要素は存在しない為、異常エラーになります。発生した例外は例1のエラーメッセージからもわかるように「ArrayIndexOutOfBoundsException」です。この例外と一致する例外クラスを指定している10行目のcatchブロックが選択され処理が実行されます。

例2では、catchブロックの例外クラスにExceptionを指定しています。このExceptionクラスはほとんどの例外クラスのスーパークラスとなっています。つまりサブクラスである「ArrayIndexOutOfBoundsException」もExceptionクラスに属しているので、Exceptionを指定したcatchブロックが処理されます。Exceptionを例外クラスとして指定すれば、ほとんどの例外はこのcatchブロックの処理が実行されます。

finally

【例4】

public class Sample{
    public static void main(String[] args) {
        int[] array = {0,1,2};
        try{
            System.out.println("try処理");
        }
        catch (Exception e){
            System.out.println("例外処理");
        }
        finally{
            System.out.println("finally処理");
        }
    }
}
try処理
finally処理

【例5】

public class Sample{
    public static void main(String[] args) {
        int[] array = {0,1,2};
        try{
           System.out.println(array[3]);
        }
        catch (Exception e){
            System.out.println("例外処理");
        }
        finally{
            System.out.println("finally処理");
        }
    }
}
例外処理
finally処理

例4は例外が発生していません。例5は例外が発生しています。結果をみると例4と例5両方でfinallyブロックが処理が実行されていることがわかります。finallyブロックは例外の発生有無に関係なく必ず最後に実行される処理です。

Exceptionのサブクラス

AclNotFoundException ActivationException
AlreadyBoundException ApplicationException
AWTException BackingStoreException
BadAttributeValueExpException BadBinaryOpValueExpException
BadLocationException BadStringOperationException
BrokenBarrierException CertificateException
ClassNotFoundException CloneNotSupportedException
DataFormatException DatatypeConfigurationException
DestroyFailedException ExecutionException
ExpandVetoException FontFormatException
GeneralSecurityException GSSException
IllegalAccessException IllegalClassFormatException
InstantiationException InterruptedException
IntrospectionException InvalidApplicationException
InvalidMidiDataException InvalidPreferencesFormatException
InvalidTargetObjectTypeException InvocationTargetException
IOException JMException
LastOwnerException LineUnavailableException
MidiUnavailableException MimeTypeParseException
NamingException NoninvertibleTransformException
NoSuchFieldException NoSuchMethodException
NotBoundException NotOwnerException
ParseException ParserConfigurationException
PrinterException PrintException
PrivilegedActionException PropertyVetoException
RefreshFailedException RemarshalException
RuntimeException SAXException
ServerNotActiveException SQLException
TimeoutException TooManyListenersException
TransformerException UnmodifiableClassException
UnsupportedAudioFileException UnsupportedCallbackException
UnsupportedFlavorException UnsupportedLookAndFeelException
URISyntaxException UserException
XAException XMLParseException
XPathException

例外クラスの一覧です。各クラスの詳しい説明はJavaマニュアルを参考にしてください。


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です