아이템 69. 예외는 진짜 예외 상황에만 사용하라
예외를 잘못 사용한 예
배열의 끝에 도달하면 끝을 내는 코드이다.
try {
int i = 0;
while(true)
range[i++].climb();
} catch (ArrayIndexOutOfBoundsException e) {
}
애플리케이션 로직을 제어할 용도로 예외가 아닌데 예외를 사용하는 것은 코드를 헷갈리게 하고 성능을 떨어뜨린다.
- 무슨 일을 하는 코드인지 직관적이지 않다.
- 코드를 try-catch 블록 안에 넣으면 JVM이 적용할 수 있는 최적화가 제한된다.
- 실제로 예외를 사용한 쪽이 반복문을 제대로 사용했을 때보다 훨씬 느렸다.
- 반복문 몸체에서 의도한 시나리오 외에 다른
ArrayIndexOutOfBoundsException
을 만났을 때 예외를 무시하기 때문에 버그를 찾기 힘들어진다.
예외는 오직 예외 상황에서만 써야한다.
- 절대로 이상적인 제어 흐름용으로 쓰여선 안된다.
- 더 좋은 성능을 낼 것이라 기대하여 쓸 수도 있지만 실제로 JVM 최적화가 더 뛰어난 경우가 많다.
- API 설계에도 마찬가지로 클라이언트가 정상적인 제어 흐름에서 예외를 사용할 일이 없게 해야 한다.
Iterator
인터페이스의 next()
나 hasNext()
와 같은 ‘상태 검사’ 메서드를 함께 제공
- ‘상태 검사’ 메서드 대신 옵셔널이나 특정 값 중 하나를 사용할 수도 있다.
- 외부 동기화 없이 여러 스레드가 동시 접근이 가능하거나 외부 요인으로 상태가 변할 수 있다면 옵셔널이나 특정 값을 사용한다.
- 성능이 중요한 상황에서 상태 검사 메서드가 상태 의존적 메서드의 작업 일부를 중복 수행한다면 옵셔널이나 특정 값을 선택한다.
- 상태 검사 메서드는 가독성도 좋고 호출을 잊어도 예외가 발생하지만 특정 값은 검사하지 않고 지나쳐도 발견하기 어렵다. (옵셔널은 해당하지 않음)