Java

Java의 Checked Exception Unchecked Exception

notion image
자바의 오류는 크게 3가지로 나눌 수 있습니다.
  • 체크 예외(CheckedException)
  • 언체크 예외(UncheckedException)

특징

예외에는 2가지로 나눌 수 있습니다.
  • 체크 예외(CheckedException): RuntimeException의 하위 클래스가 아닌 Exception 클래스의 하위 클래스들
  • 언체크 예외(UncheckedException): RuntimeException의 하위 클래스들

요약

CheckedException: 예외처리를 확인하는 Exception 클래스들 UncheckException: 컴파일러가 예외처리를 확인하지 않는 RuntimeException 클래스들

체크 예외(CheckedException)

반드시 예외 처리를 해야하는 특징(try/catch or throw)을 가지고 있습니다.
실행하기 전에 예측 가능한 예외 → 복구가 가능한 예외들이기 때문에 반드시 예외를 처리하는 코드를 작성해야한다.

예시

  • 존재하지 않는 파일의 이름을 입력(FileNotFoundException)
  • 실수로 클래스의 이름을 잘못 적음(ClassNotFoundException)

언체크 예외(UncheckedException)

체크 예외와는 달리 예외 처리를 강제하지 않습니다.
실행 중에(Runtime) 발생할 수 있는 예외를 의미합니다.
실행하고 난 후에 알 수 있는 예외 → 명시적으로 예외처리를 강제하지 않음
프로그램에 오류가 있을 때 발생하도록 의도된 것이다.

예시

  • 배열의 범위를 벗어난(ArrayIndexOutOfBoundsException)
  • 값이 null이 참조변수를 참조(NullPointerException)

특징

주의: 이 항목은 스프링 프레임워크에서의 RuntimeException에서 기본값으로 두었을 때만 해당됩니다.
중요한 점은 Rollback의 여부입니다.
  • 체크 예외: Rollback이 되지 않고 트랜잭션이 commit까지 완료됩니다.
  • 언체크 예외: Rollback이 됩니다.

활용

CheckedException vs UncheckedException 선택하기

  • 컴파일 시 반드시 예외 처리를 해야할 경우에만 CheckedException을 사용
  • 실행 시 예외를 처리할 수 있는 경우에는 RuntimeException 클래스를 확장해 UncheckedException을 사용
  • 호출하는 쪽에서 복구하리라 여겨지는 상황이면, CheckedException을 사용하라.
  • 복구할 수 있는 상황이면 CheckedException을, 프로그래밍 오류라면 UncheckedException을
  • 확실하지 않다면, UncheckedException을
  • 하지만 CheckedException을 남용하면 사용하기 곤란하다.
    • 복구할 방법이 없다면, UncheckedException을 던지자.
  • 복구가 가능하고 호출자가 그 처리를 해주길 바란다면, 옵셔널을 반환해도 될지 고민하자.
    • 옵셔널만으로 상황을 처리하기에 충분한 정보를 제공할 수 없다면
      • CheckedException을 던지자.

면접 질문

Error와 Exception의 차이를 설명해주세요.

  • 에러(Error): 프로그램 코드에 의해서 수습될 수 없는 심각한 오류 (Ex. OutOfMemoryError, StackOverflowError) / 개발자가 예측하기도 쉽지 않고 처리할 수 있는 방법도 없습니다.
  • 예외(Exception): 프로그램 코드에 의해서 수습될 수 있는 다소 미약한 오류 / 프로그램 실행 중에 개발자의 실수로 예기치 않은 상황이 발생했을 때
 
  • Error는 실행 중 일어날 수 있는 치명적 오류를 말합니다. 컴파일 시점에 체크할 수 없고, 오류가 발생하면 프로그램은 비정상 종료되며 예측 불가능한 UncheckedException에 속합니다.
  • 반면, Exception은 Error보다 비교적 경미한 오류이며, try-catch를 이용해 프로그램의 비정상 종료를 막을 수 있습니다.

CheckedException과 UncheckedException의 차이를 설명해주세요.

  • CheckedException은 실행하기 전에 예측 가능한 예외를 말하고, 반드시 예외 처리를 해야 합니다.
    • 대표적인 Exception - IOException, ClassNotFoundException 등
  • UncheckedException은 실행하고 난 후에 알 수 있는 예외를 말하고, 명시적으로 예외처리를 하지 않아도 됩니다.
    • 대표적인 Exception - NullPointerException, ArrayIndexOutOfBoundException 등
  • UncheckedException은 RuntimeException을 상속한 클래스들, CheckedException은 RuntimeException이 아닌 것을 상속한 클래스들.

예외 상황이 발생했을 때, 위의 개념을 이용하여 예외를 처리하는 적절한 방식에 대해 설명해주세요.

  • 예외 상황을 파악하고 문제를 해결해서 정상 상태로 복구하는 예외 복구 방식
  • 예외 처리를 직접 담당하지 않고 호출한 쪽으로 넘기는 예외 처리 회피
  • 적절한 예외로 전환해서 넘기는 예외 전환 방식이 있다.
  1. 무책임하게 상위 메서드에 throw로 예외를 던지는 것은 상위 메서드의 책임이 증가하기 때문에 좋지 않은 방법이다.
  1. 따라서 예외 복구 전략이 명확하고 복구가 가능하다면 Checked Excetpion을 try-catch로 잡아서 예외를 복구하는 것이 좋습니다.
  1. 복구가 불가능한 Checked Exception이 발생하면 더 구체적인 Unchecked Exception을 발생시키고 예외에 대한 메시지를 명확하게 전달하는 것이 좋습니다.

CheckedException과 UncheckedException 발생 시 Spring에서 트랜잭션 처리는 각각 어떻게 되나요?

  1. 체크드는 롤백하지 않고
  1. 언체크드는 운영상의 이슈이므로, Spring 기본값으로 해당하는 연산을 전부 취소하고 롤백함(undo)

개발하시면서 런타임에러를 경험한 적이 있는지, 실제로 사용되고있는 서비스의 경우 어떻게 해결하셨을지 궁금합니다.

@Transactional 어노테이션과 UncheckedException의 관계는 어떻게 될까요?

  1. 트랜잭션 어노테이션은 특이하게 모든 경우의 수를 따져 try catch해서 throw 하지않으면 런타임에러가 발생되지 않아, 예외처리가 어렵다.

출처

이펙티브 자바 3/E