1. 검사 예외
검사 예외 (Checked Exception)는 컴파일 시점에서 반드시 처리해야 하는 예외이다. 해당 예외를 반드시 try-catch 으로 처리하거나, throws 키워드를 사용해 호출한 메서드로 전달해야 한다.
검사 예외는 발생한 문제를 프로그래머가 처리하여 안전성을 높이게 해준다. 하지만 과하게 사용하진 말자.
(API 를 제대로 사용해도 발생할 수 있는 예외거나, 의미 있는 조치를 취할 때 외엔 비검사 예외를 사용하자)
try-catch 로 검사 예외 처리된 메소드를 사용하는 입장에서는, 또 다시 catch 블록을 두어 그 예외를 붙잡아 처리하거나, 더 바깥으로 문제를 또 다시 던져야만 한다. 그렇다면, 검사 예외와 비검사 예외 중 어느 것을 선택해야할까? 아래 두 예시는, 프로그래머가 검사 예외를 책임지는 방식이다.
} catch (TheCheckedException e) {
throw new AssertionError();
}
상위로 예외를 던져버리자.
} catch (TheCheckedException e) {
e.printStackTrace();
System.exit(1);
}
에러 스택 코드를 발생시키고 프로그램을 종료시키자.
검사 예외가 단 하나뿐이라면, 그 때문에 API 사용자는 try 블록을 추가해야하고 스트림에선 아예 사용을 못하게된다.
이러한 이유로, 검사 예외를 회피하는 방법을 알고 있어야 한다.
2. 검사 예외를 회피하기
가장 쉬운 방법은, 적절한 결과 타입을 담은 옵셔널을 반환하는 것이다.
검사 예외를 던지는 대신 단순히 빈 옵셔널을 반환하는 것이다. 하지만 이는 예외가 발생한 이유를 알려주는 부가 정보를 담을 수 없다는 단점이 있다.
두 번째 방법으로, 검사 예외를 던지는 메서드를 2개로 쪼개 비검사 예외로 바꾸는 것이다.
2개를 상태 검사 메서드, 비검사 예외를 던지는 메서드로 사용하면 된다. 아래 예시를 보자.
try {
Obj.action(args);
} catch (TheCheckedException e) {
//do something
}
검사 예외를 던지는 메서드이다. 이를 2개의 메서드로 쪼개 리팩토링 해보자.
if (obj.actionPermitted(args)) {
obj.action(args);
} else {
//do something
}
이렇게 하면 검사 예외를 피할 수 있다. 상태 검사 메서드 (actionPermitted) 를 통해, 예외가 던져질지 여부를 boolean 값으로 반환받는 것이다. 하지만, 이 리팩터링을 모든 상황에 적용할 수는 없다. 그래도 적용만 할 수 있다면 더 쓰기 편한 API 를 제공할 수 있다. 만약 이 메서드가 성공하리라는 걸 안다거나, 실패 시 스레드를 중단하길 원한다면 그냥 비검사 예외로 한 줄 작성하자.
obj.action(args)
물론 상태 검사 메서드 (actionPermitted) 를 통해 단점이 밝혀질 수 있다. 외부 동기화 없이 여러 스레드가 동시에 접근할 수 있거나 외부 요인에 의해 상태가 변할 수 있기 때문이다. 이 땐 해당 리팩터링이 적절하지 않다. actionPermitted 와 action 호출 사이에 객체의 상태가 변할 수 있기 때문이다.

'1️⃣ 백앤드 > 이펙티브 자바' 카테고리의 다른 글
| [아이템73] 추상화 수준에 맞는 예외를 던져라 (0) | 2024.12.05 |
|---|---|
| [아이템72] 표준 예외를 사용하라 (0) | 2024.12.03 |
| [아이템70] 복구할 수 있는 상황에는 검사 예외를, 프로그래밍 오류에는 런타임 예외를 사용하라 (0) | 2024.12.02 |
| [아이템69] 예외는 진짜 예외 상황에만 사용해라 (0) | 2024.12.02 |
| [아이템56] 공개된 API 요소에는 항상 문서화 주석을 작성하라 (1) | 2024.11.28 |