第16章 例外処理
例外処理に関する基本的な考え方について説明します
homepage
# **例外処理** *** Javaでプログラムを作成した場合、コンパイルの時点でエラーが発生する場合と実行中にエラーが発生する場合があります。 ## **1.例外(Exception)とは** プログラムは予めどういった処理をするのか、という手順を書いたものですが、状況によっては予期しない事象で正しく処理が行えないことがあります。 そのような予期しない状況をJavaでは例外(Exception)と呼んでいます。 <br> ## **2.例外の種類** **(1)例外の種類** Javaで発生する例外は以下のようになります。 **・Error** システム上重大な回復不能な異常な事象。そもそも回復不能な重大な状況なので、プログラム側ではほとんど対応のしようがありません。(例:メモリ不足、スタックオーバーフロー、その他JRE自体に問題があり、JRE自体が停止する事象) <br> **・RuntimeException** 実行時に起こった例外で必ずしも対処しなくても良い事象。例外処理を書くか書かないかは状況によります。プログラムのバグの可能性も多いので、プログラムを修正することが正しい対応となる場合もあります。 例えば、以下のような場合が該当します。 Stringの数字をintの整数に変換しようとしたがそもそも数字ではなかった(NumberFormatException) ``` String s = "abc"; int j = Integer.parseInt(s); ``` インスタンスがある前提でプログラムは書かれているのに存在しなかった(NullPointerException) <br> **・Exception** 上記以外の例外。例外の処理を行う必要がある。 Exceptionは、例外処理を書かなければ、コンパイルに通らないので例外処理の記述を強制されます。これにより、想定外の状況をなるべく無くすことが可能となります。 Exceptionの代表的な例としては、ファイルを開こうとしたが対象のファイルが存在しなかった(FileNotFoundException)、などです。 <br> **(2)checked例外とunchecked例外** checked例外は、コンパイル時にチェックされる例外。 上記の`Exception`クラス以下の例外 unchecked例外は、コンパイル時にチェックされない例外。 上記の`Error`クラスと`RuntimeException`クラス以下の例外 <a href="https://docs.oracle.com/javame/config/cdc/ref-impl/cdc1.1.2/jsr218/ja/java/lang/package-tree.html" target="_blank">クラス階層を参照ください。</a> #### **例1** [ArithmeticExceptionTest.java] ``` package JException public class ArithmeticExceptionTest { public static void main(String[] args) { System.out.println(" Exception in thread \"main\""); for (int i = 10; i > 0; i--) { System.out.print(" " + (i / (i - 1))); if (i % 5 == 0) System.out.println(); } } } ``` #### **実行結果** Exception in thread "main"<br> 1<br> 1 1 1 1 1<br> 1 1 2java.lang.ArithmeticException: / by zero<br> at Error.ArithmeticException.main(ArithmeticException.java:8) <br> #### **例2** [Checked_UnCheckedExceptionDemo.java] ``` package JException public class Checked_UnCheckedExceptionDemo { public static void main(String[] args) { uncheckedFunction1(); //実行中、uncheck exception発生、実行中止 uncheckedFunction2(); try { checkFunction(); }catch (MyCheckException e){ throw new RuntimeException(e); } } public static void uncheckedFunction1() { //メソッドの中に、exception発生、必ず処理。try-catch Or throw System.out.println("uncheckedFunction1()が実行された"); throw new NullPointerException(); } public static void uncheckedFunction2() throws IllegalArgumentException { System.out.println("uncheckedFunction2()が実行された"); // 呼び出し時、catchしない } public static void checkFunction() throws MyCheckException { System.out.println("invoke test3"); //check exception発生、必ず処理。try-catch } } class MyCheckException extends Exception { public MyCheckException() { super(); } } ``` #### **実行結果** uncheckedFunction1()が実行された<br> Exception in thread "main" java.lang.NullPointerException<br> at Error.Checked_UnCheckedExceptionDemo.uncheckedFunction1(Checked_UnCheckedExceptionDemo.java:19)<br> at Error.Checked_UnCheckedExceptionDemo.main(Checked_UnCheckedExceptionDemo.java:6) <br> ## **3.例外の処理方法** 例外処理は以下の2つの方法があります。 * 自分で例外を処理する * 自分では処理せず、例外処理を呼び出し元のクラスにスルーする ### **3-1.自分で例外を処理する** 基本的な書式は次の通りです。 <pre><code>try{ 例外が発生しているかどうか調べる文1; 例外が発生しているかどうか調べる文2; ... } catch (例外クラス1 変数名1){ 例外クラス1の例外が発生した時に行う文; ... } catch (例外クラス2 変数名2){ 例外クラス2の例外が発生した時に行う文; ... } </code></pre> 必ず実行する処理の記述(try..catch..**finally**) <pre><code>try{ 例外が発生しているかどうか調べる文1; 例外が発生しているかどうか調べる文2; ... } catch (例外クラス1 変数名1){ 例外クラス1の例外が発生した時に行う文; ... } catch (例外クラス2 変数名2){ 例外クラス2の例外が発生した時に行う文; ... } finally { 例外が発生するしないに関わらず実行する文; ... } </code></pre> finally中の処理は、try文の中で例外が発生してもしなくても**必ず**実行されます。 その為、**必ず**行っておきたい処理がある場合にはfinallyブロックを用意してブロック内に記述するようにして下さい。 <br> ### **3-2.例外を呼び出し元へスルーする** 呼び出し元へスルーする場合は、メソッドのシグニチャにthrows句を記述します。 ``` public void read() throws FileNotFoundException, IOException { //メソッド内容 } ``` *** > **練習** >> **問題**[JEx16_1.java] 上記例1の例外を処理ください。
content
戻る