■ 예외는 예외 진짜 예외 상황에서만 사용하라
아래 코드는 예외를 잘못 사용한 코드이다. 무한 루프를 돌다가 배열의 끝에 도달해 예외가 발생하면 끝을 내는 코드이다.
try {
int i = 0;
while(true)
range[i++].climb();
} catch (ArrayIndexOutOfBoundsException e) {
}
반복문에서 배열의 크기보다 커졌는지 검사를 하는 부분을 줄이려고 의도한 코드 였을 텐데, 이는 잘못된 추론이다.
- 예외는 예외 상황에 쓸 용도로 설계되었으므로 JVM 구현자 입장에서는 명확한 검사만큼 빠르게 만들어야 할 만큼 최적화에 신경쓰지 않았을 확률이 높다.
- 코드를 try-catch 블록 안에 넣으면 JVM이 적용할 수 있는 최적화가 제한된다.
- 배열을 순회하는 표준 관용구는 앞서 걱정한 중복 검사를 수행하지 않는다. JVM이 알아서 최적화해서 없애준다.
즉, 코드를 헷갈리게 할 뿐만 아니라 성능을 떨어뜨리고 심지어 제대로 동작하지 않을 수도 있다.
● 예외는 오직 예외 사오ㅘㅇ에서만 사용하라. 절대로 흐름 제어용으로 사용하면 안된다.
● 잘 설계된 API라면 클라이언트가 정상적인 제어 흐름에서 예외를 사용할 일이 없게 해야 한다.
■ 상태 검사 메서드
상태 의존적 메서드는 반드시 상태 검사 메서드도 함께 제공해야 한다.(Iterator의 next, hasNext)
for (Iterator<Foo> i = collections.iterator(); i.hasNext();) {
Foo foo = i.next();
// ...
}
아래 코드는 상태 검사 메서드가 없을 때 예외 처리로 처리하고 있는 코드 이다.
try {
Iterator<Foo> i = collection.iterator();
while (true) {
Foo foo = i.next();
// ...
}
} catch (NoSuchElementException e) {
}
■ 참고사항
- 외부 동기화 없이 여러 스레드가 동시 접근 가능하거나 상태가 변할 수 있다면 옵셔널을 사용한다.
- 성능이 중요한 상황에서 상태 검사 메서드가 상태 의존적 메서드의 작업 일부를 중복 수행한다면 옵셔널 반환을 선택한다.
- 그 외의 경우에는 상태 검사 메서드 방식이 더 낫다.
'Effective Java' 카테고리의 다른 글
[Effective Java] 아이템71 필요 없는 검사 예외 사용은 피하라 (0) | 2021.08.22 |
---|---|
[Effective Java] 아이템70 복구할 수 있는 상황에는 검사 예외를, 프로그래밍 오류에는 런타임 예외를 사용하라 (0) | 2021.08.22 |
[Effective Java] 아이템68 일반적으로 통용되는 명명 규칙을 따르라 (0) | 2021.08.01 |
[Effective Java] 아이템67 최적화는 신중히 하라 (0) | 2021.08.01 |
[Effective Java] 아이템66 네이티브 메서드는 신중히 사용하라 (0) | 2021.08.01 |