자바 예외

장원재·2024년 4월 8일
0

java

목록 보기
7/19
post-thumbnail

1. 자바 예외 계층

Error vs Exception
Error: 메모리 부족 처럼 어플리케이션에서 복구 불가능한 예외 계층
Exception: 개발자가 복구 가능한 예외가 포함된 계층

  • 기본적으로 자바의 예외는 체크 예외와 언체크 예외로 나뉜다.
  • 체크 예외가 대부분이고 언체크 예외로는 RuntimeException이 있다.
  • 참고로 Exception을 상속받으면 체크 예외이다.

2. Check vs Uncheck Exception

먼저 예외에 대한 규칙은 예외를 밖으로 던지거나 처리한다 이다. 체크 예외는 예외를 밖으로 필수적으로 던져야 하며, 반대로 언체크(런타임) 예외는 예외를 밖으로 던질 필요가 없다. (언체크(런타임) 예외는 throws 명시를 안해주면 자동으로 밖으로 던져준다) 코드로 하나씩 알아보자

2-1) Check Exception code

    /**
     * Exception을 상속받은 예외는 체크 예외가 된다.
     */
    static class MyCheckedException extends Exception {
        public MyCheckedException(String message) {
            super(message);
        }
    }
    static class Repository {
        public void call() throws MyCheckedException {
            throw new MyCheckedException("ex");
        }
    }
  • MyCheckedException 클래스는 Exception 클래스를 상속받기 때문에 체크 예외이다
  • 따라서 MyCheckedException 예외 클래스는 던질려면 필수적으로 명시해줘야 한다. ex) method() thorws MyCheckedException
    static class Service {
        Repository repository = new Repository();

        /**
         * 예외를 잡아서 처리하는 코드
         */
        public void callCatch() {
            try {
                repository.call();
            } catch (MyCheckedException e) {
                log.info("예외 처리, message={}", e.getMessage(), e);
            }
        }

        /**
         * 체크 예외를 밖으로 던지는 코드
         * 체크 예외는 예외를 잡지 않고 밖으로 던지려면 throws 예외를 필수로 선언해야 한다
         */
        public void callThrow() throws MyCheckedException {
            throw new MyCheckedException("ex");
        }
    }
  • 예외를 잡아주기 위해서는 try catch 에서 catch 문에서 처리하면 된다.
  • 예외를 밖으로 던지려면 throws 해주면 된다.

2-2) Uncheck(Runtime) Exception

    /**
     * RuntimeException을 상속받은 예외는 언체크 예외가 된다
     */
    static class MyUncheckedException extends RuntimeException {
        public MyUncheckedException(String message) {
            super(message);
        }
    }
    static class Repository {
        public void call() {
            throw new MyUncheckedException("ex");
        }
    }
  • RuntimeException 클래스를 상속받은 MyUncheckedException 클래스는 언체크 예외이다. 따라서 throws 를 필수적으로 명시할 필요가 없다.
  • 예외를 잡는 방법은 Check Exception 과 동일하다.

3. 그래서 이 2개의 Exception 언제 뭘 쓰는데?

결론부터 말하자면 RuntimeException 을 기본적으로 사용하고, 정말 중요한 비즈니스 로직만 체크 예외를 사용하면 된다. (Id, Password 불일치, 계좌이체 실패 등..) 이러한 이유에는 총 2가지가 있다.

1) 넘겨받은 예외를 처리하지 못한다.

  • 만약에 repository 계층에서 sqlException 이 발생했다고 해보자. 그래서 throws 로 service, controller 계층이 sqlException 처리할 수 있을까?
  • sqlException 은 공통 예외 계층까지 가야지 해결이 가능할 것이다. 즉, 체크 예외를 사용하면 예외 처리도 불가능한데 계속해서 throws 를 사용해 예외만 던지는 상황이 반복되는 것이다.

2) 다른 계층에서 의존관계 문제가 생긴다

  • 위 그림처럼 사용하는 기술 스택이 변경되어 sqlException 에서 jpaException 으로 예외가 바뀌었다고 생각해보자. 그러면 Service, Controller 계층은 모든 throws 내용들을 변경해줘야 한다.

따라서 위의 2가지 이유로 기본적으로 RuntimeException 을 사용하되, 중요한 로직만 CheckExcetion 을 사용하도록 하자. 그리고 서블릿 오류 페이지에서 공통적으로 예외를 다루자.

profile
데이터 분석에 관심있는 백앤드 개발자 지망생입니다

0개의 댓글

관련 채용 정보