Java
Java의 Checked Exception Unchecked Exception
자바의 오류는 크게 3가지로 나눌 수 있습니다.
에러(Error)
체크 예외(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이 아닌 것을 상속한 클래스들.
예외 상황이 발생했을 때, 위의 개념을 이용하여 예외를 처리하는 적절한 방식에 대해 설명해주세요.
- 예외 상황을 파악하고 문제를 해결해서 정상 상태로 복구하는 예외 복구 방식
- 예외 처리를 직접 담당하지 않고 호출한 쪽으로 넘기는 예외 처리 회피
- 적절한 예외로 전환해서 넘기는 예외 전환 방식이 있다.
- 무책임하게 상위 메서드에 throw로 예외를 던지는 것은 상위 메서드의 책임이 증가하기 때문에 좋지 않은 방법이다.
- 따라서 예외 복구 전략이 명확하고 복구가 가능하다면 Checked Excetpion을 try-catch로 잡아서 예외를 복구하는 것이 좋습니다.
- 복구가 불가능한 Checked Exception이 발생하면 더 구체적인 Unchecked Exception을 발생시키고 예외에 대한 메시지를 명확하게 전달하는 것이 좋습니다.
CheckedException과 UncheckedException 발생 시 Spring에서 트랜잭션 처리는 각각 어떻게 되나요?
- 체크드는 롤백하지 않고
- 언체크드는 운영상의 이슈이므로, Spring 기본값으로 해당하는 연산을 전부 취소하고 롤백함(undo)
개발하시면서 런타임에러를 경험한 적이 있는지, 실제로 사용되고있는 서비스의 경우 어떻게 해결하셨을지 궁금합니다.
@Transactional 어노테이션과 UncheckedException의 관계는 어떻게 될까요?
- 트랜잭션 어노테이션은 특이하게 모든 경우의 수를 따져 try catch해서 throw 하지않으면 런타임에러가 발생되지 않아, 예외처리가 어렵다.
출처
이펙티브 자바 3/E