[Item 73] 추상화 수준에 맞는 예외를 던지라
2022. 8. 28. 12:14ㆍJAVA/Effective Java
메서드가 저수준 예외를 처리하지 않고 바깥으로 전파했을 때
- 수행하려는 일과 관련 없어 보이는 예외가 발생
- 내부 구현 방식을 드러내어 윗 레벨API를 오염
- 구현 방식을 바꾸면 다른 예외가 발생하여 기존 클라이언트 프로그램을 깨지게함.
예외 번역(exception translation)
- 위 문제를 피하기 위해선 상위 계층에서 저수준 예외를 잡아 자신의 추상화 수준에 맞는 예외로
바꿔 던져야한다.(예외 번역)
try{
//저수준 추상화를 이용
}catch(LowerLevelException e){
//추상화 수준에 맞게 번역
throw new HigherLevelException("exception");
}
//AbstractSequentialList에서 수행하는 예외번역 예시
public abstract class AbstractSequentialList<E> extends AbstractList<E> {
/**
* Sole constructor. (For invocation by subclass constructors, typically
* implicit.)
*/
protected AbstractSequentialList() {
}
/**
* Returns the element at the specified position in this list.
*
* <p>This implementation first gets a list iterator pointing to the
* indexed element (with <tt>listIterator(index)</tt>). Then, it gets
* the element using <tt>ListIterator.next</tt> and returns it.
*
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E get(int index) {
try {
return listIterator(index).next();
} catch (NoSuchElementException exc) {
throw new IndexOutOfBoundsException("Index: "+index);
}
}
}
예외를 번역할 때, 저수준 예외가 디버깅에 도움이 된다면 예외 연쇄 (exception chaining)를 사용하는 게 좋다.
예외 연쇄(exception chaining)
- 예외 연쇄는 문제의 근본 원인인 저수준 예외를 고수준 예외에 실어내는 방식
try{
//저수준 추상화를 이용
}catch(LowerLevelException e){
//저수준 예외를 고수준 예외에 실어보낸다.
throw new HigherLevelException(e);
}
상위 클래스의 생성자에 이 원인을 건내주어 최종적으로 Throwable 생성자까지 건내게 된다.
그러면 별도의 접근자 메서드(Throwable의 getCause 메서드)로 언제든 저수준 예외를 꺼내볼 수 있다.
class HigherLevelException extends Exception {
HigherLevelException(Throwable cause) {
super(cause);
}
}
- Throwable의 initCause 메서드로 원인을 직접 못받을 수도 있다.
- 예외 연쇄는 문제의 원인에 접근하여 원인과 고수준 예외의 스택 추적 정보를 잘 통합해준다.
- 예외를 무턱대고 전파하는 것보다 예외 번역이 우수하지만, 남용하면 안된다. -> 가능하면 저수준 메서드가 성공하도록 하여 예외를 발생시키지 않는 것이 최선이다.
- 아래 계층에서 예외를 피할 수 없다면, 상위 계층에서 조용히 처리하여 API 호출자까지 전파하지 않는 방법이 있다. 이럴 때는 발생한 예외를 적절한 로깅 기능으로 기록해 두어야 한다.
핵심정리
- 아래 계층의 예외를 예방하거나 스스로 처리할 수 없고, 그 예외를 상위계층에 그대로 노출하기 곤란하다면 예외 번역을 사용하라.
- 이 때 예외 연쇄를 사용하면 상위 계층에는 맥락에 어울리는 고수준 예외를 던지면서 근본 원인도 함께 알려주어 오류 분석에 좋다.
참고자료
이펙티브 자바 3/E - 교보문고
프로그래밍인사이트 | 자바 6 출시 직후 출간된 『이펙티브 자바 2판』 이후로 자바는 커다란 변화를 겪었다. 그래서 졸트상에 빛나는 이 책도 자바 언어와 라이브러리의 최신 기능을 십분 활용
www.kyobobook.co.kr
'JAVA > Effective Java' 카테고리의 다른 글
[Item 75] 예외의 상세 메시지에 실패 관련 정보를 담으라 (0) | 2022.09.25 |
---|---|
[Item 74] 메서드가 던지는 모든 예외를 문서화하라 (0) | 2022.08.28 |
[Item 72] 표준 예외를 사용하라 (0) | 2022.08.28 |
[Item 71] 필요 없는 검사 예외 사용은 피하라 (0) | 2022.08.28 |
[Item 70] 복구할 수 있는 상황에는 검사 예외를, 프로그래밍 오류에는 런타임 예외를 사용하라 (1) | 2022.08.28 |