Effective Java 2/E - Chatper 09 예외 (2)
Rule 61 - 추상화 수준에 맞는 예외를 던져라
상위 계층 추상화에 맞는 예외로 변환해서 던져야 한다.
example
Exception chaining(예외 연결)
예외 스택을 통해서 하위 예외를 추적할 수 있다.
주의사항
남용하면 안 된다.
가능하면 하위계층에서 예외가 생기지 않도록 하는 것이다.
- 하위계층 호출 시 인자 유효성 강화
- 치명적인 상황(경고수준)이면 상위 계층에서 하위계층 예외를 격리시킨다. 이 때 로깅을 꼭 남기도록 한다.
- 추후 해당 오류를 분석해야함
Rule 62 - 메서드에서 던져지는 모든 예외에 대해 문서를 남겨라
모든 예외를 javadoc @throws
를 통해서 명확하게 기술한다.
일반적인 예외를 던지는 것은 금한다.
- ex)
throws Exception
,throws Throwable
무점검 예외를 통해서 메서드를 성공적으로 호출하기 위한 선행 조건을 알 수 있다.
throws
를 이용할 시에는 점검예외만 사용하자. 무점검 예외는 javadoc 문서만으로도 충분하다.
- 점검지정예외와 무점검지정예외를 구분하는 일반적인 규약이다.
동일한 예외(ex:NullPointerException
)를 던지는 메서드가 많다면 메서드 마다문서를 만들지 않고,
햬당 예외 클래스에 문서화 해도 된다.
Rule 63 - 어떤 오류인지를 드러내는 정보를 상세한 메시지에 담으라
오류 정보를 포착해 내기 위해서는, 오류의 상세 메시지에 예외에 관계된 모든 인자와 필드의 값을 포함 시켜야한다.
- 예외 상세메세지 : 예외 원인을 파악하는 메세지
- 사용자 레벨 오류 메시지 : 어플리케이션을 이용하는 최종사용자(end user)를 위한 메시지
Rule 64 - 실패 원자성 달성을 위해 노력하라
실패 원자성
메소드의 호출이 정상적으로 처리되지 못한 객체의 상태는, 메서드 호출 전 상태와 동일해야 한다. 이 속성을 만족하는 메서드는 실패 원자성(failure atomicity) 을 갖추었다고 한다.
실패원자성을 만족하는 방법
1. 불변 객체
불변 객체를 만들면 생성자를 기반하기 때문에 실패원자성은 자동으로 만족한다. 객체 생성 or 실패
2. pre check validation
실패할 가능성이 있는 코드를 전부 객체 상태를 바꾸는 코드 앞에 배치
3. Roleback
오류가 발생하면 복구코드가 연산 전 상태로 객체를 되돌린다
4. Temporary copy?
객체의 복사본 상에서 필요한 연산을 수행하고, 연산이 정상적으로 완료되면 임시 복사본의 내용을 객체 상태로 변경
Collection
정렬 시 권장 - 만약 정렬이 실패해도 원본은 그대로 유지
실패원자성을 달성할 수 없는 경우
- 멀티쓰레드를 통해 안전하지 않은 상태 객체 상태 제어 시 : 애초에 객체 일관성이 깨지고 복구를 어떤 쓰레드를 기준으로 해야할지 모호해짐
- 복구 비용이 심각하게 커지는 경우
만약 실패원자성을 만족하지 못한다면 *API문서에 어떻게 변하는지** 서술해야 한다.
Rule 65 - 예외를 무시하지 마라
무조건 예외는 catch
해야한다.
적어도 catch
블록 안에는 로그라도 남기고 그것마저 필요없다면 예외를 무시해도 괜찮은 이유라도 주석을 남겨두어야한다.