例外


🧀 例外


プログラムを作成するプログラマが通常の処理から逸脱している場合、プログラムを処理する方法を「例外」(Exception)と呼びます.

エラー発生時


2つの数に分ける方法を作ってみましょう.2つの数値10と0をパラメータとして入力し、プライマリ呼び出しメソッドでエラーが発生しました.
public void divide(){
        System.out.print("계산결과는 ");
        System.out.print(this.left/this.right); // 에러
        System.out.print(" 입니다."); // 에러
    }
これは10/0をしたために発生したエラーです.このメソッドのマスターを次のように変更します.
 public void divide(){
        try {
            System.out.print("계산결과는 ");
            System.out.print(this.left/this.right);
            System.out.print(" 입니다.");
        } catch(Exception e){
            System.out.println("오류가 발생했습니다 : "+e.getMessage());
        }
上のコードに示すように、MethodDivideの本文を修正し、メインからパラメータ(10,0),(10,5)を入力します.(10,0)出力계산결과는 오류가 발생했습니다 : / by zero、出力계산결과는 2 입니다..このコードを実行すると、上記の例とは異なり、エラーは発生しません.動作は通常のアプリケーションのようです.これはtry-catchゲートを使用したためです.

🧀 例外構文


try-catch文

try-catch文は例外の中で核心的な役割を果たす文法要素である.
try {
	예외의 발생이 예상되는 로직 
} catch (예외 클래스 인스턴스) {
	예외가 발생했을 때 실행되는 로직 
}

try


tryでは、論理を異常が発生すると位置決めします.

catch


catchには,異常が発生した場合の善後処理に用いる論理がある.

例外クラスとインスタンス

} catch(Exception e){
    System.out.println("오류가 발생했습니다 : "+e.getMessage());
}
上のコードでは、eは変数です.この変数の前のExceptionはeのデータ型を表します.Exceptionはjavaがデフォルトで提供するクラスで、java.langに属します.
e.getMessage()はjavaが伝達するインスタンスのメソッドでメッセージを呼び出すコードであり、getMessageはエラーの原因を理解しやすい形で返すことを約束する.

Exception eの使用

  • e.getMessage()エラーに関する基本内容を簡単に出力します.
  • e.toString()e.getMessage()よりも詳細な例外情報を提供します.上記のコードは、数学計算中に発生した例外であり、実行時にjava.lang.ArithmeticExceptionの例外が発生します.
  • e.printStackTrace()printStackTraceには戻り値がありません.このメソッドを呼び出すと、メソッドは内部で例外結果を画面に出力し、上のe.getMessage()またはe.toString()よりも詳細な例外情報を提供します.
  • 多様な機能


    同じ論理でも、場合によっては他の例外が発生する可能性があります.
  • ArrayIndexOutOfBoundsException
    存在しない値を取得しようとしたときに発生する異常
  • ArithmeticException
    数学計算中に発生する例外は,0などに分けられる.
  • マルチキャプチャ文


    条件文else ifのように1つのtry文に複数のcatchを使用できます.
    class Text{
        private int[] arr_ex = new int[3];
        Text() {
            arr_ex[0] = 0;
            arr_ex[1] = 10;
            arr_ex[2] = 20;
        }
        public void z(int num1, int num2) {
            try {
                System.out.println(arr_ex[num1]/arr_ex[num2]);
            } catch(ArrayIndexOutOfBoundsException e) {
                System.out.println("ArrayIndexOutOfBoundsException");
            } catch(ArithmeticException e) {
                System.out.println("ArithmeticException");
            } catch(Exception e) {
                System.out.println("Exception");
            }
        }
    }
    
    public class arr {
    
        public static void main(String[] args) {
            Text text = new Text();
            text.z(10,0); // ArrayIndexOutOfBoundsException
            text.z(1,0);  // ArithmeticException
            text.z(2,1); // Exception
        }
        
    }
    catch文を使うときも注意すべき点があります.上のコードでメソッドzのコードを修正します.
    public void z(int num1, int num2) {
            try {
                System.out.println(arr_ex[num1]/arr_ex[num2]);
            } catch(Exception e) {
                System.out.println("Exception");
            } catch(ArithmeticException e) {
                System.out.println("ArithmeticException");
            } catch(ArrayIndexOutOfBoundsException e) {
                System.out.println("ArrayIndexOutOfBoundsException");
            }
    }
    メソッドzを上のコードに変更し、再実行します.
    Exceptionは、ArrayIndexOutOfBoundsException、ArithemiticException以外の例外であるため、Exception以降に現れるcatch文は実行できません.

    try-catch-finally


    try-catch文はfinallyに使用できます.
    try{
    	예외의 발생이 예상되는 로직
    } catch (예외클래스 인스턴스) {
    	예외가 발생했을 때 실행되는 로직
    } finally {
    	예외여부와 관계없이 실행되는 로직
    }
    finallyは、try文の例外に関係なく、常に実行される論理である.今回はfinallyを使ってメソッドzの内容を修正します.
     public void z(int first, int second){
            try {
                System.out.println(arr[first] / arr[second]);
            } catch(ArrayIndexOutOfBoundsException e){
                System.out.println("ArrayIndexOutOfBoundsException");
            } catch(ArithmeticException e){
                System.out.println("ArithmeticException");
            } catch(Exception e){
                System.out.println("Exception");
            } finally {
                System.out.println("finally");
            }
        }
    try内の構文が実行されると、finallyは例外ではなく実行されます.
    finallyは、完了する必要がある特定のタスクに使用されます(例外ではありません).

    🧀 Throws


    例外強制

     public static void main(String[] args) {
            BufferedReader bReader = new BufferedReader(new FileReader("out.txt"));
            String input = bReader.readLine();
            System.out.println(input); 
        }
    コードを記述するときに、論理の異常処理を求める場合があります.例えば、次のような結果になった場合、例外処理が必要であることを示します.
    Exception in thread "main" java.lang.Error: Unresolved compilation problems: 
        Unhandled exception type FileNotFoundException
        Unhandled exception type IOException
    Unhandled exception type FileNotFoundExceptionとは、FileReaderに関連する論理が例外処理を必要とすることを意味する.

    Constructor


    Java公式ドキュメントを使用してFileReaderについて説明します.

    Parametersの下にThrowsというものがあります.
    Throwsは、どのような場合にエラーが発生するかを示します.写真の内容は、生成者FileReaderのパラメータFileNameの値に対応するファイルがディレクトリである場合、または何らかの理由で使用できない場合、FileNotFoundExceptionを生成するものです.
    FileReaderの作成者は、操作中にファイルを開くことができない場合があります.この場合、作成者FileReaderはこの問題を処理できないため、作成者のユーザーに処理を依頼します.これを投げと形容する.したがって,APIのユーザは例外を処理しなければならない.

    処理例外:try-catch文の使用

     public static void main(String[] args) {
            BufferedReader bReader = null;
            String input = null;
            try {
                bReader = new BufferedReader(new FileReader("out.txt"));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            try{
                input = bReader.readLine();
            } catch (IOException e){
                e.printStackTrace();
            }       
            System.out.println(input); 
        }
  • クラスBuffereadReaderのメソッドリード線はIO拡張を生成することができる.
  • throw vs throws


    上記では例外処理法で「try-catch-finally」を学習した.それ以外にthrowを使う方法もあります.throwは異常処理を次のユーザに渡す.
  • try-catch文
  • を使用
    import java.io.*;
    
    class B{
        void run() {
            BufferedReader bReader = null;
            String input = null;
            try {
                bReader = new BufferedReader(new FileReader("out.txt")); // FileReader의 생성자
            } catch(FileNotFoundException e) {
                e.printStackTrace();
            }
    
            try {
                input = bReader.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            System.out.println(input);
        }
    }
    class C{
        void run() {
            B b = new B();
            b.run();
        }
    }
    
    public class excode {
        public static void main(String[] args) {
            C c = new C();
            c.run();
        }
    }
  • throws文
  • を使用
    import java.io.*;
    
    class B{
        void run() throws IOException, FileNotFoundException{
            BufferedReader bReader = null;
            String input = null;
            bReader = new BufferedReader(new FileReader("out.txt")); // FileReader의 생성자
            input = bReader.readLine();
            System.out.println(input);
        }
    }
    class C{
        void run() throws IOException, FileNotFoundException{
            B b = new B();
            b.run();
        }
    }
    
    public class excode {
        public static void main(String[] args) {
             C c = new C();
             try {
                c.run();
            } catch (FileNotFoundException e) {
                System.out.println("out.txt 파일은 설정 파일 입니다. 이 파일이 프로젝트 루트 디렉토리에 존재해야 합니다.");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }   
    }
    try-catchゲートがクリアされ、throws IOException, FileNotFoundExceptionが追加されました.これは、b.run内部で IOException, FileNotFoundExceptionの異常が発生した場合、その処理をb.runのユーザに委任することを意味する.B.runのユーザーはC.runです.

    🧀 例外の作成

    class Calculator{
        int left, right;
        public void setOprands(int left, int right){        
            this.left = left;
            this.right = right;
        }
        public void divide(){
            if(this.right == 0){
                throw new ArithmeticException("0으로 나누는 것은 허용되지 않습니다.");
            }
            try {
                System.out.print("계산결과는 ");
                System.out.print(this.left/this.right);
                System.out.print(" 입니다.");
            } catch(Exception e){
                System.out.println("\n\ne.getMessage()\n"+e.getMessage());
                System.out.println("\n\ne.toString()\n"+e.toString());
                System.out.println("\n\ne.printStackTrace()");
                e.printStackTrace();
            }
        }
    } 
    public class CalculatorDemo {
        public static void main(String[] args) {
            Calculator c1 = new Calculator();
            c1.setOprands(10, 0);
            c1.divide();
        }
    }
    throwは例外を生じる.throwの後ろには、Java仮想マシンがクラスに基づいてどのcatch構文を実行するかを決定する例外情報を含む例外クラスがあります.実行するcatch構文では、異常クラスから異常の原因に関する様々な情報を取得できます.

    Javaが提供するデフォルトの例外。


    Java APIドキュメントでクラスExceptionのサブクラスを理解しましょう.

    IOException


    IOExceptionはcatch文またはthrowを試してみる必要があります.同じExceptionでも、IOExceptionのような特殊なものがあります.

    Throwable


    クラスArithemeticExceptionは、Exceptionのサブクラスです.クラスExceptionにはより多くの例外が含まれていますが、クラスArithemicExceptionはより具体的な状況を指定しています.継承関係をよく観察するとjava.lang.Throwable類がある.透過性のあるAPIドキュメントレベルの内容を確認してください.

    checked異常とunchecked異常

  • checked異常:Exceptionのサブクラス、RuntimeExceptionを含まない
    →異常処理が必要
  • 異常なし:RuntimeExceptionのサブクラス
    →異常処理ができる、
  • をしなくても良い
    Reference
    1. ライフコード例外1
    2. ライフコード例外2
    3. ライフコード例外3