• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

체크예외와 런타임예외의 차이점

23.04.25 14:31 작성 조회수 492

0

수업과 직접적으로 관련있다고 보긴 어려운 질문이지만, 체크예외와 런타임예외에 대해서 궁금증이 생겨서 질문 남깁니다!

아래 코드는 잘 실행됩니다. 그리고 IllegalStateException 오류가 잡히고 로그가 남습니다.

 @Test
    void b(){
        try {
            ex2();
        }catch (IllegalStateException e) {
            log.error("message",e);
        }
    }

    private void ex2() throws RuntimeException{
        RuntimeException ex = new IllegalStateException();
        throw ex;
    }

그러나 아래 코드는 오류를 제공합니다.

@Test
    void a(){
        try {
            ex1();
        }catch (SQLNonTransientException e) {
            log.error("message",e);
        }
    }

    private void ex1() throws SQLException{
        SQLException ex = new SQLNonTransientException();
        throw ex;
    }

ex1()에서 java.sql.SQLException 오류가 발생합니다.

첫 번째 코드가 성공하고 IllegalStateException 오류가 잡히고 로그가 남으므로 두 번째 코드도 성공해야 한다고 생각합니다.

SQLNonTransientException은 SQLException의 하위 예외이므로 IllegalStateException은 RuntimeException의 하위 클래스이기 때문입니다.

런타임 에러일 때 에러가 발생하면 지정된 하위 에러로 잡을 수 있는데 Check예외인 SQLException의 경우에는 적용되지 않는 이유를 알고 싶습니다.

답변 1

답변을 작성해보세요.

1

y2gcoder님의 프로필

y2gcoder

2023.04.25

안녕하세요, 조시현 님. 공식 서포터즈 y2gcoder 입니다.

제가 조시현님께서 궁금해하시는 바를 정확하게 이해했는지 모르겠습니다.

혹시 두 테스트 코드에서

b()에서는 아무런 에러가 뜨지 않는데 a()에서는 try-catch로 ex1()를 잡아줘도 SQLException을 처리해주라는 컴파일 에러가 뜨는 것 때문에 질문 주신 것일까요?

해당 에러는 체크 예외와 언체크 예외(이하 런타임 예외)의 차이점 때문에 발생하는 것입니다. 아시다시피 체크 예외는 컴파일러가 예외 처리를 확인하고 강제하는 예외입니다. 반면에 런타임 예외는 예외 처리를 강제하지 않는 예외입니다.

이 점을 기억하고 보시면 ex2()에서는 throws에서 런타임 예외인 RuntimeException을 throws절로 호출하는 메서드에 전달하고 있고, ex1()에서는 체크 예외인 SQLException을 throws절에서 호출하고 있습니다.

ex2()를 호출한 b()에서는 ex2()의 throws절의 예외가 런타임 예외이기 때문에 컴파일러에서 강제로 예외를 처리하라고 하지 않습니다. 그래서 에러가 발생하지 않습니다. 반면 ex1()를 호출한 a()에서는 ex1()가 throws절에 체크 예외인 SQLException을 명시했기 때문에 이를 호출한 a()에서 SQLException에 대해 try-catch 문으로 처리를 해주거나 a()에서도 throws 절을 이용해 해당 예외를 전달해주는 등의 처리가 강제됩니다. 그래서 ex1()의 throws절을 SQLNonTransientException으로 바꿔주면 해당 컴파일 에러가 사라지게 됩니다.

감사합니다.

조시현님의 프로필

조시현

질문자

2023.04.25

b()에서는 RuntimeException으로 에러를 던져줬음에도 불구하고 runtimeException의 하위에러이자 참조하고 있는 객체인 IllegalStateException로 예외를 잡아서 log를 나타내주는데

a()의 경우에는 SQLException의 하위에러이자 참조하고 있는 객체인 SQLNonTransientException로 왜 잡아주지 못하고 SQLException으로 잡아줘야하는지 궁금했습니다.

질문이 불친절해서 죄송합니다 ㅠㅠ

y2gcoder님의 프로필

y2gcoder

2023.04.25

아닙니다. ㅎㅎ
그리고 밑의 질문에 대한 답이 이것입니다. ex1()의 throws절에 SQLException이라 명시했기 때문에 이를 호출하는 a()에서 해당 에러도 잡아줘야 한다고 컴파일러가 강제하는 것이 원인입니다. 체크 예외기 때문에 컴파일러가 throws 절에 있는 SQLException도 처리하라고 하는 것입니다.

제가 위의 답변을 너무 장황하게 드린 것 같아 죄송합니다.

조시현님의 프로필

조시현

질문자

2023.04.25

감사합니다! 최고최고 최고입니다!! 시원하게 해결되었습니다! 날씨가 꿀꿀한데 좋은 하루 되세요~

y2gcoder님의 프로필

y2gcoder

2023.04.25

파이팅입니다!