// 69-1 예외를 완전히 잘못 사용한 예 - 따라하지 말 것!
try {
int i = 0;
while(true) { // 절대 좋지 않은 코드
range[i++].climb();
}
} catch (ArrayIndexOutOfBoundsException e){
}
// 표준적인 관용구로 하면 이해하기 쉽고 try는 필요하지 않다,
for (Mountain m : range) {
m.climb();
}
for ( Iterator<Foo> i = collection.iterator(); i.hashNext(); ) {
Foo foo = i.next();
...
}
// 컬렉션을 이런 식으로 순회하지 말 것!
try {
Iterator<Foo> i = collection.iterator();
while (true) {
Foo foo = i.next();
...
}
} catch (NoSuchElementException e){
}
70. 복구할 수 있는 상황에는 검사 예외를, 프로그래밍 오류에는 런타임 예외를 사용하라
71. 필요 없는 검사 예외 사용은 피하라
// 검사 예외와 비검사 예외 중 어느 것을 선택해야 할지는 프로그래머가 그 예외를 어떻게 다룰지 생각해보면 알 수 있다.
} catch (TheCheckedException e) {
throw new AssertionError(); // 일어날 수 없다!
}
} catch (TheCheckedException e) {
e.printStackTrace(); // 이런, 우리가 졌다.
System.exit(1);
}
// 71-1 검사 예외를 던지는 메서드 - 리팩토링 전
try {
obj.action(args);
} catch (TheCheckedException e) {
... // 예외 상황에 대처한다.
}
// 71-2 상태 검사 메서드와 비검사 예외를 던지는 메서드 - 리팩토링 후
if (obj.actionPermitted(args) {
obj.action(args);
} else {
... // 예외 상황에 대처한다.
}
obj.action(args);
72. 표준 예외를 사용하라
73. 추상화 수준에 맞는 예외를 던지라
// 73-1 예외 번역
try {
... // 저수준 추상화를 이용한다.
} catch (LowerLevelException e) {
// 추상화 수준에 맞게 번역한다.
throw new HigherLevelException();
}
/**
* 이 리스트 안의 지정한 위치의 원소를 반환한다.
* @throws IndexOutOfBoundsException index가 범위 밖이라면,
* 즉 ({@code index < 0 || index >= size()})이면 발생한다.
*/
public E get(int index) {
ListInterator<E> i = listInterator(index);
try{
return i.next();
} catch (NoSuchElementException e) {
throw new IndexOutOfBoundsException("인덱스: " + index);
}
}
// 73-2 예외 연쇄
try {
... // 저수준 추상화를 이용한다.
} catch (LogwerLevelException cause) {
// 저수준 예외를 고수준 예외에 실어 보낸다.
throw new HigherLevelException(cause);
}