ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [자바의 정석] 예외처리
    JAVA 2022. 10. 19. 18:31
    728x90
    반응형

    예외처리 (Exception handling)

    프로그램 오류에는 컴파일 에러, 런타임 에러로 나눌 수 있습니다.

    • 런타임 에러에는 다시 에러(Error)와 예외(Exception)로 나뉩니다.
    종류 의미
    컴파일 에러 컴파일 할 때 발생하는 에러
    런타임 에러 실행 할 때 발생하는 에러

    런타임 에러

    종류 의미
    에러 (Error) 프로그램 코드에 의해서 수습될 수 없는 심각한 오류
    예외 (Exception) 프로그램 코드에 의해서 수습될 수 있는 다소 미약한 오류
    예외의 경우는 꼭 예외 처리를 해줘야한다.

    예외 처리는 프로그램 실행 시 발생할 수 있는 예외의 발생에 대비한 코드를 작성하는 것을 말한다.

    예외처리 구문

    예외를 처리하려면 try - catch문을 사용해야 한다.

    try{
        // 예외가 발생할 가능성이 있는 문장
    } catch(Exception1 e1){
        // Exception1에 해당하는 예외가 발생하면 이를 처리할 문장
    } catch(Exception2 e2){
        // Exception2에 해당하는 예외가 발생하면 이를 처리할 문장
    } catch(Exception3 e3){
        // Exception3에 해당하는 예외가 발생하면 이를 처리할 문장
    }

    try - catch문의 흐름

    try 블록 내에서 예외가 발생한 경우

    1. 발생한 예외와 일치하는 catch블록이 있는지 확인한다.
    2. 일치하는 catch블록이 있다면 해당 catch블록에 있는 문자를 수행한다.
      • 만약 일치하는 catch블록이 없다면 예외처리가 되지 않았기 때문에 프로그램이 실행되지 않는다.
    3. try-catch문 전체를 빠져나오고 다음 코드부터 실행한다.

    try블록 내에서 예외가 발생하지 않은 경우

    1. catch블록을 모두 무시하고 빠져나오고 다음 코드부터 실행한다.
    public class ExceptionTest{
        public static void main(String[] args){
            System.out.println(1);
            System.out.println(2);
            
            try{
                System.out.println(3);
                System.out.println(4);
                System.out.println(0/0); // 예외 발생
                System.out.println(5);
            } catch(Exception e){
                System.out.println(6);
            }
            
            System.out.println(7);
        }
    }
    
    // 결과 1 2 3 4 6

    예외 발생시키기

    예외는 고의로 발생시킬 수 있다.

    1. new 연사자를 이용해서 발생시키려는 예외 클래스의 객체를 만든다.
    2. 키워드 throw를 통해서 예외를 발생시킨다.
    try{
        Exception e = new Exception("고의로 발생시키는 예외");
        throw e;
        // 위 두줄을 한줄로 줄이면 throw new Exception("고의로 발생시키는 예외"); 가 된다.
    } catch(Exception e){
        System.out.println("에러 메시지 : " + e.getMessage());
        e.printStackTrace();
    }
    System.out.println("프로그램이 정상 종료되었습니다.");
    
    
    // 결과
    // 에러 메시지 : 고의로 발생시키는 예외
    // java.lang.Exception : 고의로 발생시키는 예외 at public클래스이름.main(public클래스이름.java:예외 발생 위치)
    // 프로그램이 정상 종료되었습니다.

    예외 클래스의 계층구조

    예외 클래스는 크게 예외처리가 필수인 그룹과 예외처리가 선택인 그룹으로 나눌 수 있습니다.

    RuntimeException 클래스 그룹 : 프로그래머의 실수로 발생하는 예외(예외처리 필수)
    Exception 클래스 그룹 : 사용자의 실수와 같은 외적인 요소로 발생하는 예외(예외처리 선택)

    Exception

    • IOException (입출력 예외)
    • ClassNotFoundException (클래스가 존재하지 않는다.)
    • ...
    • RuntimeException
      • ArithmeticException (산술 계산 예외 ) 예를 들어 5/0
      • ClassCastException (형 변환 예외)
      • NullPointerException (널 포인트 예외) 예를 들어 "String str = null; str.length;"
      • ...
      • IndexOutOfBoundsException (배열 범위를 벗어난 예외)
    예외 클래스의 최고 조상인 Exception은 반드시 마지막 catch블록에 사용해야 한다.
    만약 첫 번째 때 사용한다면 정확히 어떤 예외인지 알 수 없기 때문이다.
    System.out.println(1);
    System.out.println(2);
    try{
        System.out.println(3);
        System.out.println(0/0); // ArithmeticException 발생
        System.out.println(4);
    } catch(ArithmeticException ae){
        System.out.println("true");
        System.out.println("ArithmeticException");
    } catch(Exception e){
        System.out.pritnln("Exception");
    }
    System.out.println(6);
    
    // 결과 1 2 3 true ArithmeticException 6

    finally 블록

    예외의 발생 여부와 처리 여부에 관계없이 무조건 실행되어야 하는 코드를 넣는 곳이다.

    • 예외 발생 시에는 "try > catch > finally" 순서로 실행
    • 예외 미발생시에는 "try > finally" 순서로 실행
    • try 혹은 catch 블록에서 return문을 만나도 finally블록은 수행된다.
    try{
        // 예외 발생 가능성이 있는 문장
    } catch(Exception1 e1){
        // Exception1 예외처리를 위한 문장
    } finally{
        // 예외 발생여부에 관계없이 실행되는 문장
        // finally 블록은 맨마지막에 위치해야한다.
    }

    메서드에 예외 선언하기

    예외처리 방법 중 하나이며 실제로는 예외를 처리하는 게 아닌 메서드를 호출한 곳으로 예외를 전달시키는 것입니다.

    • 호출한 곳에서 예외를 처리해야만 할 때 사용됩니다.
    // 사용방법
    void method() throws Exception1, Exception2, ..., ExceptionN{
        // 메서드 수행할 문장
    }
    import java.io.*;
    
    public class ExceptionTest{
        public static void main(String[] args){
            try{
                File f = createFile(args[0]); // 메서드가 전달하고자 하는 예외는 이쪽으로 전달된다.
                System.out.println(f.getName() + "파일이 성공적으로 생성되었습니다.");
            } catch(Exception e){
                System.out.println(e.getMessage() + "다시 입력해 주시기 바랍니다.");
            }
        }
        static File createFile(String fileName) throws Exception{
            if(fileName == null || fileName.equals("")){
                throw new Exception("파일 이름이 유효하지 않습니다.");
            }
            File f = new File(fileName); // File 클래스의 객체를 만든다.
            f.createNewFile(); // createNewFile 메서드를 이용해서 실제 파일을 생성한다.
            return f; // 생성된 객체의 참조를 반환한다.
        }
    }

    예외 되던지기 (re-throwing)

    예외를 처리한 후에 다시 예외를 생성하여 호출한 메서드로 전달하는 것을 말하며 예외가 발생한 메서드와 호출한 메서드 양쪽에서 예외를 처리해야 하는 경우 사용된다.

    public class ExceptionTest{
        public static void main(String[] args){
            try{
                method1(); // method1 메서드에서 예외가 전달된다 5
            } catch(Exception e){ // 예외처리 6
                System.out.println("main 메서드에서 예외처리 되었습니다.");
            }
        }
        static void method1() throws Exception{ 4
            try{
                throw new Exception(); // 고의로 예외 발생 1
            } catch(Exception e){ // 예외처리 2
                System.out.println("method1 메서드에서 예외처리 되었스니다.");
                throw e; // 다시 예외를 발생 시킨다. 3
            }
        }
    }
    
    // 결과
    // method1 메서드에서 예외처리 되었습니다.
    // main 메서드에서 예외처리 되었습니다.

    사용자 정의 예외 만들기

    기존의 예외 클래스를 상속받아서 새로운 예외 클래스를 정의할 수 있다.

    class MyException extends Exception{
        private final int ERR_CODE; // 상수
        
        MyException(String msg, int errCode){ // 생성자
            super(msg);
            ERR_CODE = errCode; // 생성자를 통해 상수 초기화
        }
        MyException(String msg){
            this(msg, 100); // MyException(String msg, int errCode) 생성자 호출
            // ERR_CODE는 기본값으로 100으로 초기화 된다.
        }
        
        public int getErrCode(){
            return ERR_CODE;
        }
    }
    728x90
    반응형
Designed by Tistory.