운이 없다면 언젠가 다음과 같은 코드와 마주칠지도 모른다.
try {
int i = 0;
while(true) {
range[i++].climb();
}
} catch(ArrayIndexOutOfBoundsException e) {
}
무슨 일을 하는 코드인지 알겠는가? 전혀 직관적이지 않다는 사실 하나만으로도 코드를 이렇게 작성하면 안 되는 이유는 충분하다.
이 코드는 배열의 원소를 순회하는데, 아주 끔찍한 방식으로 하고 있다.
무한루프를 돌다가 배열에 끝에 도달에 ArrayIndexOutOfBoundsException이 발생하면 끝을 내는 것이다.
이 코드를 다음과 같이 표준적인 관용구대로 작성했다면 모든 자바 프로그래머가 곧바로 이해했을 것이다.
for(Mountain m : range) {
m.climb();
}
그런데 예외를 써서 루프를 종료한 이유는 도대체 뭘까?
잘못된 추론을 근거로 성능을 높여보려 한 것이다.
JVM은 배열에 접근할 때마다 경계를 넘지 않는지 검사하는데, 일반적인 반복문도 배열 경계에 도달하면 종료한다.
따라서 이 검사를 반복문에도 명시하면 같은 일이 중복되므로 하나를 생략한 것이다.
하지만 세 가지 면에서 잘못된 추론이다.
실상은 예외를 사용한 쪽이 표준 관용구보다 훨씬 느리다. 내 컴퓨터에서 원소 100개짜리 배열로 테스트해보니 2배 정도 느렸다.
예외를 사용한 반복문의 해악은 코드를 헷갈리게 하고 성능을 떨어뜨리는 데서 끝나지 않는다.
심지어 제대로 동작하지 않을 수도 있다.