ジャワ挑戦記-14


本日学習例外処理
異常処理(異常処理)
プログラムエラー
プログラムが実行中に何らかの理由で誤操作や異常終了する場合があります.この結果の原因をプログラムエラーまたはエラーと呼ぶ.
コンパイルエラー:コンパイル時に発生したエラー
ランタイムエラー:ランタイムに発生したエラー
論理エラー:実行できますが、動作と意図は異なります.
エラーが発生した場合、プログラムの異常終了を阻止することはできませんが、例外が発生しても、プログラマは対応するコードを作成することでプログラムの異常終了を阻止することができます.
エラー(error):プログラムコードで処理できない重大なエラー
異常(exception):プログラムコードによる軽微なエラー
例外クラスの階層
すべてのクラスの祖先はObjectクラスなので、ExceptionとErrorクラスもObjectクラスの子孫です.
RuntimeExceptionクラスおよびそのサブクラスをRuntimeExceptionクラスと呼び、RuntimeExceptionクラスを除く他のクラスをExceptionクラスと呼ぶ.
RuntimeExceptionクラスは、Javaのプログラミング要素と密接に関係するプログラマのエラーによる例外です.たとえば、配列外の参照変数(ArrayIndexOutOfBoundsException)、値が空のメンバー(Null PointerException)、またはクラス間の変換エラー(ClassCastException)を呼び出そうとします.整数をゼロに除算しようとすると発生します
Exceptionクラスは主に外部の影響によるものであり,通常はプログラム中のユーザの行為によるものである.たとえば、存在しないファイルの名前(FileNotFoundException)、クラス名(ClassNotFoundException)が誤って入力された場合、または入力されたデータ型が無効な場合(DataFormatException)
Exceptionクラス:ユーザーエラーなど外部要因による異常
RuntimeExceptionクラス:プログラマのエラーによる例外
例外の処理-try-catch文
異常処理(Exception Handling)は、プログラムの実行中に発生する可能性のある予期せぬ異常のためのコードを記述し、異常処理の目的は、異常の発生による実行中のプログラムの突然の異常終了を防止し、正常な運転状態を維持することである.
例外処理の
定義:プログラムの実行中に発生する可能性のある例外のコードを記述します.
目的-プログラムが終了し、正常な動作を維持しないようにする
例外を処理するためにtry-catch文を使用します.その構造は次のとおりです.
try{
    //예외가 발생할 가능성이 있는 문장들을 넣는다
}catch(Exception1 e1){
    //Exception1이 발생했을 경우, 이를 처리하기 위한 문장을 적는다
}catch(Exception2 e2){
    //Exception2이 발생했을 경우, 이를 처리하기 위한 문장을 적는다
}catch(ExceptionN eN){
    //ExceptionN이 발생했을 경우, 이를 처리하기 위한 문장을 적는다
}
try-catch文のストリーム
try blockで異常が発生しました.
1.発生した異常と一致するcatch blockがあるか確認する
2.一致するcatch blockが見つかった場合、そのcatch block内の文を実行し、try-catch文全体を終了して次の文を実行します.一致するcatch blockが見つからない場合は、例外を処理できません.
try blockで異常が発生していない場合.
1.catch blockを通さずにtry-catchゲート全体から出て実行を続ける
class ExceptionEx{
    public static void main(String[] args) {
        System.out.println(1);
        System.out.println(2);
        try{
            System.out.println(3);
            System.out.println(0/0);
            System.out.println(4);
        }catch(ArithmeticException ae){
            System.out.println(5);
        }
        System.out.println(6);
    }
}
異常の具体値とcatch block
catch blockはカッコ()とblock{}の2つの部分に分けられ、カッコ()内に処理する例外などのタイプの参照変数を宣言する必要があります.
printStackTrace():例外発生時にスタック内のメソッドを呼び出す情報と例外メッセージを画面に出力します.
getMessage():発生した例外クラスインスタンスに格納されたメッセージを取得できます.
public class ExceptionEx {
    public static void main(String[] args) {
        System.out.println(1);
        System.out.println(2);
        try{
            System.out.println(3);
            System.out.println(0/0);//예외발생
            System.out.println(4);//실행 X
        }catch(ArithmeticException e){
            e.printStackTrace();
            System.out.println("예외메시지 : "+e.getMessage());
        }
        System.out.println(6);
    }
}
ArithemicExceptionインスタンスのprintStackTraceを使用して、呼び出しスタックに関する情報と例外メッセージを出力します.
try{
    ...
}catch(ExceptionA e){
    e.printStackTrace();
}catch(ExceptionB e2){
    e.printStackTrace();
}

try{
    ...
}catch(Exception A | ExceptionB e){
    e.printStackTrace();
}
catch blockは「|」記号を使用して、「multicatch block」と呼ばれるcatch blockにマージできます.
異常をきたす
キーワードthrowを使用すると、プログラマーがわざと異常を起こす可能性があります.
まず、演算子newを使用して、励起する例外クラスのオブジェクトを作成します.
  • Exception e=new Exception(「故意に発生」);
  • キーワードthrowを使用して例外を生成
  • throw e;
  • public class ExceptionEx10 {
        public static void main(String[] args) {
            try{
                Exception e = new Exception("고의로 발생시킴");
                throw e;
            }catch(Exception e){
                System.out.println("에러 메시지 : "+e.getMessage());
                e.printStackTrace();
            }
            System.out.println("프로그램이 정상 종료당함");
        }
    }
    public class ExceptionEx11 {
        public static void main(String[] args) {
            throw new RuntimeException();
        }
    }
    RuntimeExceptionで異常終了
    メソッドに例外を宣言
    メソッドに例外を宣言するには、メソッドの宣言子にキーワードthrowsを使用してメソッドで発生する可能性のある例外を記録します.
    void method() throws Exception1, Exception2, Exception3, ..., ExceptionN{
        //메서드의 내용
    }
    メソッド宣言子に例外を宣言することで、メソッドを使用しようとする人がメソッドの宣言子を見た場合、メソッドを使用するにはどの例外を処理する必要があるかを簡単に知ることができます.
    メソッドの例外を宣言する場合、通常はRuntimeExceptionクラスが少なくありません.
    public class ExceptionEx12 {
        public static void main(String[] args) throws Exception {
            method1();
        }
    
        static void method1() throws Exception{
            method2();
        }
    
        static void method2() throws Exception{
            throw new Exception();
        }
    }
    最終ブロック
    finally block異常の有無にかかわらず実行すべきコードを含む
    try{
       //예외가 발생할 가능성이 있는 문장들을 넣는다
    }catch(Exception1 e1){
       //예외처리를 위한 문장을 적는다
    }finally {
       //예외의 발생여부에 관계없이 항상 수행되어야하는 문장들을 넣는다
       //finally블럭은 try-catch문의 맨 마지막에 위치해야한다.
    }
    例外が発生した場合はtry->catch->finallyの順に実行し、例外が発生しなかった場合はtry->finallyの順に実行します
    public class FinallyTest {
        public static void main(String[] args) {
            try {
                startInstall();//프로그램 설치에 필요한 준비를 한다
                copyFiles();//파일들을 복사한다
            }catch(Exception e){
                e.printStackTrace();
                
            }finally{
                deleteTempFiles();//프로그램 설치에 사용된 임시파일들을 삭제한다
            }
        }
        
        static void startInstall(){
            //코드를 작성한다
        }
        static void copyFiles(){
            //파일들을 복사하는 코드를 적는다
        }
        static void deleteTempFiles(){
            //임시파일들을 삭제하는 코드를 적는다
        }
    }
    自動リソース戻り-try-with-resources文
    try-with-resources文というtry-catch文のバリエーションが新しく追加されました.
    try{
        fis = new FileInputStream("score.dat");
        dis = new DataInputStream(fis);
        ...
    }catch(IOException ie){
        ie.printStackTrace();
    }finally{
        dis.close();//작업 중 예외가 발생하더라도, dis가 닫히도록 finally블럭에 넣음
    }
    最後にblockにclose()を入れますが、close()は異常を引き起こす可能性があります.
    try{
        fis = new FileInputStream("score.dat");
        dis = new DataInputStream(fis);
        ...
    }catch(IOException ie){
        ie.printStackTrace();
    }finally{
        try{
            if(dis!=null){
                dis.close();
            }
        }catch(IOException ie){
            ie.printStackTrace();
        }
    }
    try blockとfinally blockの両方に例外が発生した場合、try blockの例外は無視されます.
    これを改善するためにtry-with-resources文を追加しました.
           try(FileInputStream fis = new FileInputStream("score.dat");
               DataInputStream dis = new DataInputStream(fis)){
               while (true){
                   score = dis.readInt();
                   System.out.println(score);
                   sum += score;
               }
           }catch(EOFException e){
               System.out.println("점수의 총합은 "+sum+"입니다.");
           }catch(IOException ie){
               ie.printStackTrace();
           }
    try-with-resource文のカッコ()にオブジェクトを生成する文を挿入すると、try blockを離れるとclose()を単独で呼び出さなくてもclose()が自動的に呼び出されます.
    カスタム例外の作成
    通常はExceptionクラスまたはRuntimeExceptionクラスから継承してクラスを作成しますが、必要に応じて適切な例外クラスを選択できます.
    class MyException extends Exception{
        MyException(String msg){
            super(msg);
        }
    }
    class MyException extends Exception{
        private final int ERR_CODE;//생성자를 통해 초기화한다
        
        MyException(String msg, int errCode){
            super(msg);//조상인 Exception클래스의 생성자를 호출한다
            ERR_CODE = errCode;
        }
        
        MyException(String msg){
            this(msg,100);//ERR_CODE를 100(기본값)으로 초기화한다
        }
        
        public int getErrCode(){
            return ERR_CODE;
        }
    }
    MyExceptionが発生した場合、catchブロックでgetMessage()とgetErCode()を使用してエラーコードとメッセージを取得できます.
    public class NewExceptionTest {
        public static void main(String[] args) {
            try{
                startInstall();
                copyFiles();
            }catch(SpaceException e){
                System.out.println("에러 메시지 : "+e.getMessage());
                e.printStackTrace();
                System.out.println("공간을 확보한 후에 다시 설치하시기 바랍니다.");
            }catch(MemoryException me){
                System.out.println("에러 메시지 : "+me.getMessage());
                me.printStackTrace();
                System.gc();//Garbage Collection을 수행하여 메모리를 늘려준다
                System.out.println("다시 설치를 시도하세요.");
            }finally {
                deleteTempFiles();
            }
        }
    
        static void startInstall() throws SpaceException, MemoryException{
            if(!enoughSpace()){
                throw new SpaceException("설치할 공간이 부족합니다");
            }
            if(!enoughMemory()){
                throw new MemoryException("메모리가 부족합니다");
            }
        }
    
        static void copyFiles(){/*코드작성한다*/}
        static void deleteTempFiles(){/*코드 작성한다*/}
    
        static boolean enoughSpace(){
            //설치하는데 필요한 공간이 있는지 확인하는 코드를 작성한다
            return false;
        }
    
        static boolean enoughMemory(){
            //설치하는데 필요한 메모리공간이 있는지 확인하는 코드는 적는다
            return true;
        }
    }
    
    class SpaceException extends Exception{
        SpaceException(String msg){
            super(msg);
        }
    }
    
    class MemoryException extends Exception{
        MemoryException(String msg){
            super(msg);
        }
    }
    MemoryExceptionとSpaceExceptionは、この2つのカスタム例外クラスを作成し、使用します.
    異常投擲
    1つのメソッドに複数の可能性のある例外がある場合は、try-catch文を使用してメソッド内でいくつかの例外を独自に処理し、宣言子に指定して呼び出したメソッドで処理し、2つのメソッドで別々に処理できます.
    異常を処理した後、人為的に再発させる方法が可能であり、これを「異常放出」と呼ぶ.
    public class ExceptionEx17 {
        public static void main(String[] args) {
            try{
                method1();
            }catch(Exception e){
                System.out.println("main메서드에서 예외가 처리되었습니다");
            }
        }
    
        static void method1() throws Exception{
            try{
                throw new Exception();
            }catch(Exception e){
                System.out.println("method1메서드에서 예외가 처리되었습니다.");
                throw e;//다시 예외를 발생시킨다
            }
        }
    }
    リンク例外
    異常Aが異常Bを引き起こす場合、AをBの「原因異常(cause exception)」と呼ぶ.
    try{
        startInstall();//SpaceException 발생
        copyFiles();    
    }catch(SpaceException e){
        InstallException ie - new InstallException("설치중 예외발생");//예외 생성
        ie.initCause(e);//InstallException의 원인 예외를 SpaceException으로 지정
        throw ie;    
    }catch(MemoryException me){
        ...
    }
    まずInstallExceptionを作成し、initCause()を使用してSpaceExceptionをInstallExceptionに登録する理由が異常です.そしてthrowでこの例外を投げ出します
    InitCause()は、Exceptionクラスの親Throwableクラスで定義されているため、すべての例外で使用できます.
    Throwable initCause(Throwable cause):指定された例外を原因異常として登録します.
    Throwable getCause():原因異常を返す
    static void startInstall() throws SpaceException, MemoryException{
        if(!enoughSpace()){
            throw new SpaceException("설치할 공간이 부족합니다.");
        }
        if(!enoughMemory()){
            throw new MemoryException("메모리가 부족합니다.");
        }
    }
    
    static void startInstall() throws SpaceException{
            if(!enoughSpace()){
                throw new SpaceException("설치할 공간이 부족합니다.");
            }
            if(!enoughMemory()){    
                throw new RuntimeException(new MemoryException("메모리가 부족합니다."));
            }
    }
    Runtime Exception(Throwable cause):登録理由が異常な作成者