본문 바로가기

IT自主学習 (2023.05.23~)/Java(2023.05.23~)

プログラミング自主学習 21日目 例外(Exception)/例外の処理/例外の優先順位/例外とデバッガ/finally&resource/try with resource

例外(Exception)

System.out.println(2/0); ->error

 

Javaでは、整数を0に分けることは許されず、ログラムが停止する。このような現象を例外と呼ぶ。

 

例外の例>

・整数を0で割り算を行った。

・配列の要素数より大きい要素数を指定してアクセスした。

・ユーザーは入力間違いを行った。(数値入力を要求しているのに、英子の入力等)

・存在しないファイルを指定し、ファイルの読み込みを行った。

・データーべースに接触が行えなかった。

・割り当てられていない記憶領域へのアクセスを行った。(不正な値のポインタを参照など)

 

このような状況を予測して、例外を処理することが重要である。

 


例外の処理

try&catch

エラーが発生する可能性があるコードはtry&catchを使用して例外処理ができる。

try{エラーが発生する可能性があるコード}
catch(例外の種類 e) 
{停止されず、実行されるコード}

 

 

 

 

tryに様々なコードがあるとすれば、例外が発生したコードの下のコードは実行されない。

 

 


例外の優先順位

継承関係を考えてみると、スーパークラスであるExceptionalを使用して、全ての例外を処理することもできる。

すべての例外を Exception クラスでキャッチする場合、個々の例外に対して異なる処理を行うことはできない。

以下がその例である。

 

 

また、個々の例外をキャッチすることで様々な処理ができるが、
注意点として、スーパークラス(上位クラス)の例外処理ブロックが

サブクラス(下位クラス)の例外処理ブロックよりも前に配置される必要がある。
なぜなら、すでにスーパークラスで例外が処理されているため、

サブクラスの例外処理をする理由がないためだ。


例外とデバッガ

catchのメソッドにget.Message()メソッドを呼び出すことで、例外の原因が分かる。

 

 

また、printStackTrace()を呼び出すことで、例外が発生した位置をコンソールより把握することができる。

 

 

 


Checked Exception(チェック例外) vs Unchecked Exception(実行時例外)

 

参照:Youtube '생활코딩', Java 예외 - 6. checked vs unchecked exception

 

例外を二つには分ければ、Checked ExceptionとUnchecked Exceptionに分かれる。

 

Checked Exceptionとはコンパイラーがチェックを強制する例外である。

コンパイル時に検出され、例外が処理されない場合は、コンパイルエラーが発生する。

 

ファイルの読み込みエラー、ネットワーク接続の問題、データベースのエラーなどが一般的なチェックエラーの例である。そのため、プログラマーは必ず明示的に例外の処理を行う必要がある。

RuntimeExceptionを継承していない例外クラスであれば、チェック例外だと考えても良い。

例>IOException、FileNotFoundException

 

Unchecked ExceptionとはRuntime Exceptionを継承した例外のクラスである。

コンパイラがチェックを強制しない例外であるため、ヒューマンエラーが行いやすい。

Unchecked Exceptionが発生しても例外処理は強制されないため、プログラマーが適切な例外処理を行わない場合、

例外が無視されたり適切な対応が行われない場合がある。

したがって、開発者はUnchecked Exceptionに対する例外処理を慎重に考慮する必要がある。

例>ArrayIndexOutOfBoundsException、ArithmeticException

 

例外処理には主に二つがある。

 

1)try-catchで処理する。

try-catchを使用して、例外を通常の状態で戻したり、明示的にエラーが生じたことを知らせる。

 

 

2)throwsをして、例外を上位メッソドに投げる。例外処理を回避することである。

 

役割がきちんと分けた場合を除外して、なるべく避けるべきな行為だ。


finally&resource

Finallyは、例外の有無に関わらず必ず処理させたい場合に使う

 

例えば、クラスFileWriterのように、データーをファイルにアウトプットしたり、ネットワークのような

外部のリソースにアウトプットする場合はエラーが起こりやすい。

 

参照:youtube, '생활코딩' , Java 예외 - 7. finally와 resource 다루기

 

 

リソースに繋がった後は必ずClose(); メソッドを使用して、ファイルを閉める必要があるが、Close();メソッドより例外が発生する可能性もある。

 

public class Exception;
      public static void main(String[] args){
               FileWriter f;

           try {f=new FileWriter("data.txt");
               f.write("hello");
               f.close();  // ⇦ここから例外が発生し、catchに進めるとclose();が実行できない。
       }  catch(IOException e){  
              e.printStackTrace();   
       } 
   }
}

 

そのために活用するのはクラスFinallyのブロックである。 

public class Exception;
      public static void main(String[] args){
               FileWriter f;
    
           try {f=new FileWriter("data.txt");
               f.write("hello");      
       }  catch(IOException e){  
              e.printStackTrace();(
       }  finally {
              f.close();   
       }    

   }

 

しかし、  try {f=new FileWriter("data.txt");よりまた例外が発生する場合、FileWriter型の変数fは値を割り当てられず、そのまま、f.closeにすすむため、また例外が生じる可能性がある。

最終的にはclose()が値がある際のみ、作動する条件文を作成する。

 

FileWriter f = null; (変数に値がない)  
           try {f=new FileWriter("data.txt");
               f.write("hello");
      
       }  catch(IOException e){  
              e.printStackTrace(
       }  finally { 
           if(f!=null){       
             f.close(); 
  }
       }    

   }

 

最後に、もう一度、FileWriterのメソッドCloseの例外処理を行う。

 

 


try-with-resource

このように、リソースに関わるコードはfinallyを活用することもできるが、様々なコードが重なり、複雑になるため、ミスが起こりやすい。

そのため、Java 8よりはAuto ClosableというInterfaceができ、コードをとても簡単にまとめることができるようになった。Finallyとclose()が含めているため、明示的に表す必要もない。