[Effective Java] 아이템 71 : 필요 없는 검사 예외 사용은 피하라

Loopy·2022년 12월 10일
0

이펙티브 자바

목록 보기
69/76
post-thumbnail
post-custom-banner

🙌 들어가기

검사 예외는 제대로 활용한다면, API와 프로그램의 질을 높일 수 있다.
결과를 코드로 반환하거나 비검사 예외를 던지는 것과 달리, 발생한 문제를 프로그래머가 직접 처리하여 안전성을 높일 수 있기 때문이다.

검사 예외는 필수로 예외를 처리해야 한다는 점, 검사 예외를 던지는 메서드는 스트림 안에서 직접 사용할 수 없다는 점등으로 인해 자바 8부터 부담이 커졌다. 따라서 검사 예외는 필요한 곳에만 쓰고 남용하지 않는 것이 좋다.

비검사 예외 VS 검사 예외 선택하기

  1. 검사 예외 : API를 제대로 사용해도 발생할 수 있는 예외거나, 프로그래머가 의미 있는 조치를 취할 수 있는 경우에 사용
  2. 비검사 예외 : 복구할 방법이 없는 경우에 사용

만약 아래의 두가지 방식보다 더 나은 대안이 없다면, 비검사 예외를 선택하자.

} catch (TheCheckedException e) {
	throw new AssertionError();  // 일어날 수 없다!
}
} catch (TheCheckedException e) {
	e.printStackTrace();  // 이런, 우리가 졌다.
    System.exit(1);
}

검사 예외를 회피하는 방법

1. Optional

검사 예외를 회피하는 가장 쉬운 방법은 적절한 결과 타입을 담은 옵셔널을 반환하는 것이다.(아이템 55) 검사 예외를 던지는 대신, 단순 빈 옵셔널을 반환하면 된다.

하지만 예외를 사용할 때 구체적인 예외 타입과 그 타입이 제공하는 메서드들을 활용해 부가 정보를 제공할 수 있는 반면 옵셔널은 예외가 발생한 이유를 알려주는 부가 정보들을 담을 수 없다는 단점이 있다.

2. 상태 검사 메서드 활용

두번째로, 검사 예외를 던지는 메서드를 2개로 쪼개 상태 검사 메서드와 비검사 예외를 던지는 메서드로 바꿀 수 있다.

try {
	obj.action(args);
} catch (TheCheckedException e) {
    ... // 예외 상황에 대처한다.
}

리팩터링 하면 다음과 같다.

if (obj.actionPermitted(args)) {  // 상태 검사 메서드
	obj.action(args);
} else {
	... // 예외 상황에 대처한다.
}

하지만 아이템 69에서 얘기했듯이 상태 검사 메서드는 외부 동기화 없이 여러 스레드가 동시에 접근할 수 있거나 외부 요인에 의해 상태가 변할 수 있는 상황에서 안전하지 않다. actionPermittedaction 호출 사이에 객체의 상태가 변할 수 있기 때문이다.

📚 핵심 정리
꼭 필요한 곳에만 사용한다면 검사 예외는 프로그램의 안전성을 높여주지만, 남용하면 좋지 않은 API을 야기한다. API 호출자가 예외 상황에서 복구할 방법이 없다면 비검사 예외를 던진다. 복구가 가능하고 호출자가 그 처리를 해주길 바란다면, 우선 옵셔널을 반환해도 될지 고민하자. 옵셔널만으로는 상황을 처리하기에 충분한 정보를 제공할 수 없을 때만 검사 예외를 던져야 한다.

profile
개인용으로 공부하는 공간입니다. 잘못된 부분은 피드백 부탁드립니다!
post-custom-banner

0개의 댓글