ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Study] 자바 9주차 과제
    JAVA 2021. 1. 27. 15:47
    반응형

    9주차 과제입니다.

     

     


     

     

    자바에서 예외 처리 방법 (try, catch, throw, throws, finally)

     

    try, catch, finally

    package exception;
    
    public class Ex_Exception {
        public static void main(String[] args) {
            try {
                System.out.println("A");
                System.out.println(1 / 0); //예외 발생
                System.out.println("B"); //예외 발생 후 바로 catch 문으로 가기 때문에 실행 안됨
            }catch (ArithmeticException e) {
                System.out.println("C");
                System.out.println(e.getMessage()); //해당 throwable 객체에 대한 자세한 내용
                e.printStackTrace(); //해당 throwable 객체와 표준 오류 스트림에서 해당 객체의 스택 트레이스(stack trace)를 출력함
                //catch 문 안에 예외처리도 가능
                try {
                    System.out.println("D");
                    System.out.println(2 / 0);
                }catch (ArithmeticException e1) {
                    System.out.println("E");
                }
            }catch (Exception e) {
                //catch 문 여러 개 작성 가능
                System.out.println("F");
            }finally {
                //예외처리와 관련없이 무조건 실행됨
                System.out.println("G");
            }
        }
    }

     

     

     

     

    자바에서는 프로그램이 실행되는 도중 발생하는 예외를 처리하기 위해 try / catch / finally 문을 사용할 수 있습니다.

     

    • try 블록: 기본적으로 맨 먼저 실행되는 코드로 여기에서 발생하는 예외는 catch 블록에서 처리됩니다.
    • catch 블록: try 블록에서 발생한 예외 코드나 예외 객체를 인수로 전달받아 그 처리를 담당합니다. 
    • finally 블록: 이 블록은 try 블록에서 예외가 발생하건 안 하건 맨 마지막에 무조건 실행됩니다.

    catch 블록과 fianlly 블록은 선택적인 옵션으로 반드시 사용할 필요는 없습니다.

    따라서 사용할 수 있는 모든 적합한 try 구문은 다음과 같습니다.

    1. try / catch
    2. try / finally
    3. try / catch / ... / finally

     

     

    Multicatch block

    JDK 1.7부터 여러 catch block을 하나로 합칠 수 있게 되었습니다.

    package exception;
    
    public class Ex_Exception {
        public static void main(String[] args) {
            try {
                //try문 코드
            }catch (IllegalArgumentException | ArithmeticException e) {
                //catch문 코드
            }
        }
    }
    

     

    단, 이 때 나열된 예외 클래스들이 부모-자식 관계에 있다면 오류가 발생합니다.

    왜냐하면, 자식 클래스로 잡아낼 수 있는 예외는 부모 클래스로도 잡아낼 수 있기 때문에 사실상 코드가 중복된 것이나 마찬가지이기 때문입니다. 이 때, 컴파일러는 중복된 코드를 제거하라는 의미에서 에러를 발생시킵니다.

     

    package exception;
    
    public class Ex_Exception {
        public static void main(String[] args) {
            try {
                //try문 코드
            }catch (IllegalArgumentException | ArithmeticException e) {
                //두 예외 클래스가 부모-자식 관계라서 에러 발생
                //catch문 코드
            }
        }
    }
    

     

     

    throw, throws

    package exception;
    
    public class Ex_Exception {
        public static void main(String[] args) {
            try{
                throw new Exception("예외 발생");
            }catch (Exception e) {
                System.out.println(e.getMessage());
            }
        }
    }
    
    //출력
    //예외 발생
    

    자바에서는 throw 키워드를 사용하여 강제로 예외를 발생시킬 수 있습니다.

    위 예제처럼 생성자에 전달된 문자열은 getMessage() 메소드를 사용하여 오류 메시지로 출력할 수 있습니다.

     

    메소드 선언부에 throws 키워드를 사용하여 해당 메소드를 사용할 때 발생할 수 있는 예외를 미리 명시할 수도 있습니다.

    이렇게 하면 해당 메소드를 사용할 때 발생할 수 있는 예외를 사용자가 충분히 인지할 수 있으며, 그에 대한 처리까지도 강제할 수 있습니다.

    따라서 더욱 안정성 있는 프로그램을 손쉽게 작성할 수 있도록 도와줄 수 있습니다.

     

    package exception;
    
    public class Ex_Exception {
        public static void main(String[] args) {
            try {
                handlingException();
            }catch (Exception e) {
                System.out.println("main 메소드에서 예외가 처리됨");
            }
        }
    
        static void handlingException() {
            try {
                throw new Exception();
            }catch (Exception e) {
                System.out.println("호출된 메소드에서 예외가 처리됨");
            }
        }
    }
    
    //출력
    //호출된 메소드에서 예외가 처리됨
    

     

    이 때 호출된 메소드의 try / catch 문을 생략하면 컴파일 오류가 발생합니다.

    또한, 이 메소드를 호출한 main() 메소드는 호출된 메소드에서 예외가 발생한 사실을 알 수 없습니다.

     

    package exception;
    
    public class Ex_Exception {
        public static void main(String[] args) {
            try {
                handlingException();
            }catch (Exception e) {
                System.out.println("main 메소드에서 예외가 처리됨");
            }
        }
    
        static void handlingException() throws Exception {
            throw new Exception();
        }
    }
    
    //출력
    //main 메소드에서 예외가 처리됨
    

     

    thorws 키워드를 사용하여 호출된 메소드에서 발생한 예외를 호출한 메소드로 넘김으로써 호출된 메소드에는 try / catch 문을 생략할 수 있습니다. 그리고 호출된 메소드에서 발생한 예외를 해당 메소드를 호출한 main() 메소드에서 처리할 수 있게 됩니다.

     

     

     

     

    자바가 제공하는 예외 계층 구조

     

     

    출처 : http://www.tcpschool.com/java/java_exception_class

    모든 예외 클래스는 Throwable 클래스를 상속받고 있으며, Throwable의 최상위 클래스 Object의 자식 클래스입니다.

    Exception은 CheckedException과 UncheckedException으로 구분할 수 있으며, Exception 자식 클래스 중 RuntimeException은 UncheckedException, 그 외의 Exception은 CheckedException이라고 합니다.

    이를 구분하는 가장 큰 기준은 "꼭 처리를 해야하느냐" 입니다. RuntimeException 이외의 Exception이 발생할 가능성이 있는 코드는 반드시 예외 처리를 해주어야 합니다.

     

     

    RuntimeException과 RE가 아닌 것의 차이는?

     

    CheckedException UncheckedException
    반드시 예외 처리를 해야함 명시적인 처리를 강제하지 않음
    컴파일 단계에서 확인 실행단계에서 확인
    IOException
    FileNotFoundException
    ...

    외부적인 영향으로 발생할 수 있는 예외
    RuntimeException
    | -- ArithmeticException
    | -- NullPointerException
    ...

    실행 중 발생되는 예외

     

     

     

    Exception과 Error의 차이는?

     

    자바 프로그렘을 작성할 때 자바 문법에 맞지 않게 코드를 작성하고 컴파일하려고 하면, 자바 컴파일러는 문법 오류(syntax error)를 발생시킵니다.

    또한, 자바 문법에는 맞게 작성되었다 하더라도 프로그램이 실행되면서 예상하지 못한 오류가 발생할 수 있습니다.

    이렇게 컴퓨터 시스템이 동작하는 도중에 예상하지 못한 사태가 발생하여 실행 중인 프로그램이 영향을 받는 것을 오류(error)와 예외(exception) 두 가지로 구분할 수 있습니다.

     

    오류(error)는 시스템 레벨에서 프로그램에 심각한 문제를 야기하여 실행 중인 프로그램을 종료시킵니다.

    이러한 오류는 개발자가 미리 예측하여 처리할 수 없는 것이 대부분이므로, 오류에 대한 처리는 할 수 없습니다.

     

    하지만 예외(exception)는 오류와 마찬가지로 실행 중인 프로그램을 비정상적으로 종료시키지만, 발생할 수 있는 상황을 미리 예측하여 처리할 수 있습니다.

    따라서 개발자는 예외 처리(exception handling)를 통해 예외 상황을 처리할 수 있도록 코드의 흐름을 바꿀 필요가 있습니다.

     

     

     

    커스텀한 예외 만드는 방법

    class SubwayProgramException extends IllegalArgumentException {
        private static final String PREFIX = "[ERROR] ";
        private static final String NEWLINE = "\n";
    
        public SubwayProgramException(String errorMessage) {
            super(NEWLINE + PREFIX + errorMessage);
        }
    }
    
    public class Application {
        private static final String errorMessage = "커스텀 에러";
        public static void main(String[] args) {
            try {
                throw new SubwayProgramException(errorMessage);
            }catch (SubwayProgramException e) {
                System.out.println(e.getMessage());
            }
        }
    }
    
    //출력
    //[ERROR] 커스텀 에러
    
    

     

    기존에 정의된 예외 클래스 외에 필요에 따라 새로운 예외를 정의할 수 있습니다. 

    Exception 클래스를 상속받거나, 필요에 따라 알맞은 예외 클래스를 상속받아 만듭니다.

    getMessage() 메소드에 의해 출력되는 내용도 생성자를 통해 커스텀할 수 있습니다.

     

     

     

     

    References

     

    - i-am-clap.tistory.com/12

    - www.tcpschool.com/java/java_exception_intro

    - sujl95.tistory.com/62

    - wisdom-and-record.tistory.com/46

    728x90

    댓글

Designed by Tistory.