Skip to content

ㄴ 10장 예외

yongfucius edited this page Jun 17, 2019 · 1 revision

아이템 69 예외는 진짜 예외 상황에만 사용하라

절대로 일상적인 제어 흐름용으로 쓰여선 안된다. 잘 설계된 API라면 클라이언트가 정상적인 제어 흐름에서 예외를 사용할 일이 없게 한다.
'상태 의존적' 메서드를 제공하는 클래스는 '상태 검사' 메서드도 함께 제공해야 한다. IteratornexthasNext가 대표적인 예이다. 올바르지 않은 상태일 때 빈 옵셔널이나 null같은 특수값을 반환하는 방법도 있다.

  1. 외부 동기화 없이 여러 스레드가 동시에 접근할 수 있거나 외부 요인으로 상태가 변할 수 있다면 옵셔널이나 특정값을 사용
  2. 성능이 중요한 상황

아이템 70 복구할 수 있는 상황에는 검사 예외를, 프로그래밍 오류에는 런타임 예외를 사용하라

  • 호출하는 쪽에서 복구하리라 여겨지는 상황이라면 검사 예외 (복구에 필요한 정보도 알려주면 좋고)
  • 프로그래밍 오류를 나타낼 때는 런타임 예외
  • 애매하면 런타임 예외
  • Error, Throwable은 사용하지마

아이템 71 필요 없는 검사 예외 사용은 피하라

단 하나의 검사 예외를 던지는 상황이라면 고민해봐라. 옵셔널같은 값으로 상황을 처리하기에 충분한 정보를 제공할 수 없을때만 검사 예외를 던지자.


아이템 72 표준 예외를 사용하라

예외 주요 쓰임
IllegalArgumentException 허용하지 않는 값이 인수로 넘어왔을 때
IllegalStateException 객체가 메서드를 수행하기에 적절하지 않은 상태일 때
(인수 값이 무엇이든 실패했을 상황)
NullPointerException null을 허용하지 않는 메서드에 null을 건넸을 때
IndexOutOfBoundsException 인덱스가 범위를 넘어섰을 때
ConcurrentModificationException 허용하지 않는 동시 수정이 발견됐을 때
UnsupportedOperationException 호출한 메서드를 지원하지 않을 때

Exception, RuntimeException, Throwable, Error는 직접 사용하지마.


아이템 73 추상화 수준에 맞는 예외를 던지라

상위 계층에서는 저수준 예외를 잡아 자신의 추상화 수준에 맞는 예외로 던져야 한다. 이게 예외 번역 exception translation.
예외 번역에서 저수준 예외가 디버깅에 도움이 된다면 원인(cause)을 실어 보내는 게 좋다. 이게 예외 연쇄 exception chaining.
그렇다고 무조건 던지지말고 예외가 발생하지 않도록 하는 것이 최선이다.


아이템 74 메서드가 던지는 모든 예외를 문서화하라

검사 예외는 항상 따로따로 선언하고, 각 예외가 발생하는 상황을 자바독의 @throws 태그를 사용해라. Exception 던지지 말라는 얘기.


아이템 75 예외의 상세 메시지에 실패 관련 정보를 담으라

실패 순간에 관여된 모든 매개변수와 필드값을 메시지에 담아야 한다.


아이템 76 가능한 한 실패 원자적으로 만들라

호출된 메서드가 실패하면 해당 객체는 메서드 호출 전 상태를 유지해야 한다.


아이템 77 예외를 무시하지 말라

try {
    ...
} catch (Exception e) {
}

무시하려면 이유를 주석으로 남기고 이름도 ignored로 바꿔라.

try {
    ...
} catch (SomeException ignored) {
// 무시하고 싶어서 ㅇㅇ
}