try{
int i = 0;
while(true)
range[i++].climb();
} catch (ArrayIndexOutOfBoundsException e) {
}
for(Mountain m : range)
m.climb();
for(Iterator<Foo> i = collection.iterator(); i.hasNext();){
Foo foo = i.next();
}
try{
Iterator<Foo> i = collection.iterator();
while(true)
Foo foo = i.next();
...
} catch (NoSuchElementException e){}
-
외부 동기화 없이 여러 스레드가 동시에 접근할 수 있거나 외부 요인으로 상태가 변할 수 있다면 옵셔널이나 특정 값을 사용한다. 상태 검사 메서드와 상태 의존적 메서드 호출사이에 객체의 상태가 변할 수 있기 때문이다.
-
성능이 중요한 상황에서 상태 검사 메서드가 상태 의존적 메서드의 작업 일부를 중복 수행한다면 옵셔널이나 특정 값을 사용한다.
상태 검사 메서드: hasNext와 같은 상태를 검사하는 메서드
상태 의존적 메서드: next와 같이 상태검사 메서드에 의존적인 메서드
상태 검사 메서드가 상태 의존적 메서드의 작업 일부를 중복 수행할 경우를 말하는거 같다.
- 다른 모든 경우엔 상태 검사 메서드 방식이 조금 더 낫다고 할 수 있다. 가독성이 살짝 더 좋고, 잘못 사용했을 때 발견하기가 쉽다. 상태 검사 메서드 호출을 깜빡 잊었다면 상태 의존적 메서드가 예외를 던져 버그를 확실히 드러낼것이다. 반면 특정 값을 넘기는 방식은 지나쳐도 발견하기가 어렵다. (옵셔널은 해당하지 않는다.isPresent와 같은 상태를 검사하는 메서드가 있다.)
예외는 예외 상황에서 쓸 의도로 설계 되었다. 정상적인 제어 흐름에서 사용해서는 안되며, 이를 프로그래머에게 강요하는 API를 만들어서도 안 된다.