-
[이펙티브 자바] item 71 - 필요 없는 검사 예외 사용은 피하라개발서적읽기/Effective Java - temp 2020. 5. 21. 08:45
■검사 예외의 불편함
검사 예외를 싫어하는 개발자가 많지만 제대로 활용하면 API와 프로그램의 질을
높일 수 있다. 반면 사용이 과해지면 불편하기만 할 수도 있다.
(검사 예외를 던지는 메서드는 스트림 안에서 직접 사용할 수 없기 때문에 (item45 ~ 48)
자바 8부터는 부담이 더욱 커졌다)
검사 예외가 프로그래머에게 지우는 부담은 메서드가 단 하나의 검사 예외만
던질 때가 특히 크다. API 안에 검사 예외가 여러개 있을 때나, 하나만 있을 때나
어차피 try catch로 묶거나 throws로 던져줘야 하는건 똑같다. 그리고 이처럼 검사
예외에 대한 책임을 지게 되면 해당 메서드를 스트림에서 직접 사용할 수 없다.
검사 예외가 0개에서 1개가 되는 것은 99개에서 100개가 되는것에 비해 훨씬 큰 부담이다.
■검사 예외 회피 방법 :: 1. 비검사 예외
API를 제대로 사용해도 발생할 수 있는 예외이거나, 프로그래머가 의미 있는 조치를
취할 수 있는 경우라면 이 정도 부담쯤은 받아들일 수 있을 것이다. 하지만 이 경우들이
아니라면, 비검사 예외를 사용하는 것이 좋다. (item70)
아래 두 코드는 프로그래머(API 사용자)가 검사 예외를 책임지는 사례다.
} catch (TheCheckedException e) {
throw new AssertionError();}
} catch (TheCheckedException e) {
e.printStackTrace();
System.exit(1);
}첫 번째 코드는 프로그래머가 비검사 예외를 호출하는 것으로 해결했다.
두 번째 코드는 에러 스택 코드를 호출하고 시스템을 종료시킨다.
두 경우 모두 애초에 비검사 예외로 API를 만들면 됐을 것이다.
■검사 예외 회피 방법 :: 2. Optional
검사 예외를 회피하는 두 번째 방법은 적절한 결과 타입을 담은 옵셔널을 반환하는
것이다. (item55) 검사 예외를 던지는 대신 단순히 빈 옵셔널을 반환하면 된다. 쉽다.
하지만 이 방식은 단점이 있다. 예외가 발생한 이유를 알려주는 부가 정보를 담을 수
없다는 점이다. (예외를 사용하면 구체적인 예외 타입과 그 타입이 제공하는 메서드들을
활용해 부가 정보를 제공할 수 있다.(item70))
■검사 예외 회피 방법 :: 3. 메서드 쪼개기
검사 예외를 회피하는 세 번째 방법은 검사 예외를 던지는 메서드를 2개로 쪼개어
비검사 예외로 바꾸는 것이다. 쪼개진 첫 번째 메서드는 예외가 던져질지 여부를
boolean값으로 반환한다.
<메서드 쪼개기 before>
try {
Obj.action(args);
} catch (TheCheckedException e) {
//do something
}<메서드 쪼개기 after>
if (obj.actionPermitted(args)) {
obj.action(args);
} else {
//do something
}action 내의 로직을 2개 매소드 (actionPermitted, action) 으로 나눈 모습이다.
깔끔함을 어느정도 포기하고 유연함을 얻었다.
한편, actionPermitted는 '상태 검사 메서드'에 해당하므로 주의를 기울일 필요가 있다.
외부 동기화 없이 여러 스레드가 동시에 접근할 수 있거나 외부 요인에 의해 상태가
변할 수 있다면 이 리팩터링은 적절하지 않다. (item69)
actionPermitted와 action 호출 사이에 객체의 상태가 변할 수 있고, 또 두 메서드가
동일한 로직을 중복해서 가지고 있을 수 있기 때문이다.
■결론
꼭 필요한 곳에만 사용한다면 검사 예외는 프로그램의 안전성을 높여주지만,
남용하면 쓰기 고통스러운 API를 낳는다. API 호출자가 예외 상황에서
복구할 방법이 없다면 비검사 예외를 던지자. 복구가 가능하고 호출자가
그 처리를 해주길 바란다면, 옵셔널 사용을 검토해보자.
그래도 여의치 않으면 그때서야 검사 예외를 사용하자.
'개발서적읽기 > Effective Java - temp' 카테고리의 다른 글
[이펙티브 자바] item 26 - 로 타입은 사용하지 말라 (0) 2020.07.19 [이펙티브 자바] item 14 - Comparable을 구현할지 고려하라 (0) 2020.07.09 [이펙티브 자바] item 70 - 복구할 수 있는 상황에는 검사 예외를, 프로그래밍 오류에는 런타임 예외를 사용하라 (0) 2020.05.20 [이펙티브 자바] item 61 - 박싱된 기본 타입보다는 기본 타입을 사용하라 (0) 2020.05.15 [이펙티브 자바] item 60 - 정확한 답이 필요하다면 float와 double은 피하라 (0) 2020.05.13 댓글