[이펙티브 자바] 아이템 69. 예외는 진짜 예외 상황에만 사용하라

June·2022년 3월 9일
0

[이펙티브자바]

목록 보기
62/72
try {
    int i = 0;
    while (true)
        range[i++].climb()
} catch (ArrayIndexOutOfBoundsException e) {
}

JVM은 배열에 접근할 때마다 경계를 넘지 않는지 검사하니, 그 하나를 생략해보고자 한 코드다.
하지만 잘못 됐다.

  1. 에외는 예외 상황에 쓸 용도로 설계되었으므로 JVM 구현자가 최적화를 하지 않았을 수 있다.
  2. try-catch 블록 안에 넣으면 JVM이 적용할 수 있는 최적화가 제한된다.
  3. 배열을 순회하는 관용구는 앞서 걱정한 중복 검사를 수행하지 않게 최적화한다.

만약 버그가 숨어있었다면 이 예외가 버그를 숨겨 디버깅이 어려웠을 것이다.

예외는 예외 상황에서만 써라. 일상적인 제어 흐름용으로 쓰지 마라.

잘 설계된 API라면 클라이언트가 정상적인 제어 흐름에서 예외를 사용할 일이 없게 해야한다.
특정 상태에서만 호출할 수 있는 상태 의존적 메서드를 제공하는 클래스는 상태 검사 메서드도 함께 제공해야 한다.

  • Iterator 인터페이스의 nexthasNext 가 각각 상태 의존적 메서드와 상태 검사 메서드에 해당된다. 이러한 메서드 덕분에 for 관용구를 사용할 수 있다. for-each도 내부적으로 hasNext를 사용한다.
List<Car> cars = new ArrayList<>();
for (Iterator<Car> i = cars.iterator(); i.hasNext();) {
   ... 
}

haxNext와 같은 상태 검사 메서드도 제공해야 한다.

List<Car> cars = new ArrayList<>();
try {
    Iterator<Car> i = cars.iterator();
    while (true) {
        Car car = i.next();
    }
    
} catch (NoSuchElementException e) {
}

이런 식으로 순회하면 안된다.

상태 검사 메서드 대신 빈 옵셔널이나 null을 반환할 수 도 있다.

  1. 외부 동기화 없이 여러 스레드가 접근하거나 외부 요인으로 상태가 바뀔 수 있다면 널이나 특정 값을 사용한다.
  2. 성능이 중요한데 상태 검사 메서드가 상태 의존적 메서드의 작업 일부를 중복 수행한다면 옵셔널이나 특정 값을 선택한다.
  3. 다른 경우 상태 검사 메서드 방식이 조금 더 낫다.

0개의 댓글