목차
1. 자바의 예외
2. checked vs unchecked
3. 예외 처리 전략
자바의 예외
자바에서 예외는 크게 3가지로 나뉜다.
Exception - 검사 예외, checked Exception
RuntimeException - 비검사 예외, unchecked Exception
Error - 에러
이 중 에러는 개발자가 어떻게 처리 할 방법이 없으므로, checked, unchecked 예외를 잘 처리해야한다.
(Exception, RuntimeException, Error 전부 아닌 Throwable 객체 - 만들지 말기. 쓸데없고, 햇갈리기만 함.)
checked vs unchecked
Exception(checked) | RuntimeException (unchecked) | |
처리 여부 | 반드시 처리해야함 | 안해도 됨 |
발생 상황 | 복구할수 있는 상황. 클라이언트 잘못이 아님. |
프로그래밍 오류. 클라이언트가 전제조건을 못지킴 |
발생 시점 | 컴파일타임 | 런타임 |
(스프링) 트랜잭션 | 롤백 안됨 | 롤백 됨 |
대표적 예시 | IOException SQLExeption |
IllegalStateException NullPointerException |
(스프링) 트랜잭션 항목에 대한 추가 설명:
- unchecked 예외가 발생하면 어떤 객체를 em.save() 통해 영속화 했다고 생각했어도, DB에 저장 안되고 롤백된다.
- checked exeption 예외가 발생하면 예외 발생 전의 내용이 반영(커밋)된다.
예외 처리 전략
예외 처리 전략은
1. 예외 복구
2. 예외 회피
3. 예외 전환
이렇게 3가지가 있다.
1. 예외 복구
리소스 부족 등의 문제를 프로그래머가 해결 후 다시 실행하는것.
checked exception이 복구할수 있는 상황에 발생하는 예외이다.
final int MAX_RETRY = 100;
public Object someMethod() {
int maxRetry = MAX_RETRY;
while(maxRetry > 0) {
try {
...
} catch(SomeException e) {
// 로그 출력. 정해진 시간만큼 대기한다.
} finally {
// 리소스 반납 및 정리 작업
}
}
// 최대 재시도 횟수를 넘기면 직접 예외를 발생시킨다.
throw new RetryFailedException();
}
예외를 복구할수 있는 상황, 반드시 그래야 하는 상황은 많지 않다.
또 예외는 흐름 제어에 사용해서도, 그렇게 설계해서도 안된다.
상태 검사 메서드 - 예시) Iterator.hasNext()
를 사용하여 if else 형태의 분기문이 되도록 하거나,
Optional 혹은 약속된 특정 값을 이용하여
애초에 예외를 발생시키지 않는 방법을 먼저 고려해야한다.
(이펙티브 자바 책을 참고하세요)
2. 예외 회피
예외를 처리하지 않고 던지는 것.
예외 응집도가 낮아지고, 최악의 경우 아무 처리도 하지 않는 문제가 생길수 있기에 조심해서 사용한다.
3. 예외 전환
발생한 예외 대신 다른 예외를 발생시키는것이다.
checked exeption => unchecked exception 으로 전환할수 있다.
public void lostPw(String userEmail, String randomPw) {
final MimeMessage mimeMessage = mailSender.createMimeMessage();
final MimeMessageHelper helper; // true = multipart
try {
//메일 객체 생성 후 발송
} catch (MessagingException | IOException e ) {
e.printStackTrace();
throw new IllegalStateException("메세지 전송중 예외 발생 : lostpw");
}
mailSender.send(mimeMessage);
}
내 프로젝트에 있는 실제 코드 예시이다.
try 블록 내부에서는 MessagingException, IOException 등이 발생할수 있다.
checked 라서 반드시 처리해야하는 예외를, 그냥 catch 한 후 끝내는것이 아니라
unchecked로 전환하여 구체적 메세지를 전달하였다.
출처
1. 조슈아 블로크, 『Effective Java』, 이복연 역 (인사이트, 2018), 386 ~ 412
2. https://cheese10yun.github.io/checked-exception/#checked-exception-3
'Dev > Spring' 카테고리의 다른 글
테스트 코드와 관련 프레임워크 (0) | 2022.04.14 |
---|---|
테스트 작성과 Jacoco (0) | 2022.04.13 |
Controller와 Service의 역할에 대한 고민 (2) | 2021.12.17 |
[Lombok ] 클래스 단위로 @Builder 사용시 주의점 (0) | 2021.08.20 |
Servlet 서블릿에 대하여 (0) | 2021.07.17 |