티스토리 뷰

Item71에서는 필요 없는 Checked Exception 사용을 피하라 말한다

앞선 Item70에서 신나게 단점에 대해 얘기했으니 Checked Exception의 장점을 알아보고자 한다

다음 질문을 참고해 보자

 

In Java, what are checked exceptions good for?

Java's checked exceptions have gotten some bad press over the years. A telling sign is that it's literally the only language in the world that has them (not even other JVM languages like Groovy and...

softwareengineering.stackexchange.com

 

Checked Exception의 장점을 물어봤고 그에 대한 첫 번째 답변이 흥미롭다

주요 골자로 자신은 Checked Exception이 좋고 이 것이 에러에 강한 프로그램을 만드는데 도움을 준다는 것이다

Checked Exception 혐오자라면 이게 무슨 말 같지 않은 소리인가 싶겠다

NullPointerException을 예로 들어보자, 실무에서 NPE를 안 겪어본 이가 흔치 않을 것이다

이를 해결하는데 kotlin 같이 언어 차원에서 null을 막아버리는 우아한 해법도 있지만

자바 같이 try-catch로 감싸거나 조건문으로 처리하는 터프(?)한 해법도 있다

 

여기서 잠깐 망상을 해보자

NPE를 유발할 수 있는 행위가 Checked Exception으로 처리된다면 어떻게 될까?

즉 원시 타입이 아닌 객체 타입을 인자로 받는 모든 메서드는 강제로 try-catch를 걸어야 한다면

코드 작성자 입장에서는 너무나 괴롭고 자바를 손절치고 싶겠지만 에러 처리를 해뒀다면 NPE는 터지지 않을 것이다

현실성 없는 예시지만 Checked Exception을 이렇게도 바라볼 수 있겠구나 하고 이해하면 되겠다

컴파일 타임에 예외 처리를 하게끔 하는 그 의도 자체는 숭고하다

볼 품 없는 try-catch와 강제적으로 처리해야 한다는 점이 열 뻗침 포인트일 것이다

자바로 작성된 수많은 코드가 있기에 홀라당 코틀린으로 넘어갈 수도 없는 노릇이다

 

이왕 이렇게 된 거 Checked Exception을 즐겨보자

자신의 프로젝트에 Exception을 상속받아 예외 처리를 하라는 말은 절대 아니다

책에서 나오는 스트림에서 직접 사용할 수 없다는 부분은 아래와 같은 꼼수로 처리가 가능하다

제네릭, 람다에 익숙하다면 금방 익힐 수 있을 것이다

다만 개인적인 감상으로는 이를 완전히 이해한 이가 아니고서야 스트림에서 try-catch 좀 줄여보겠다고

오히려 코드 복잡도를 늘리는 꼴이라 실무에 적용시키기 전에 반드시 팀원의 합의를 이끌어내야 할 필요가 있다

@FunctionalInterface
public interface SupplierExceptionWrapper<T, E extends Exception> {

  static <T, E extends Exception> Supplier<T> toUnchecked(SupplierExceptionWrapper<T, E> f) {
    return toUnchecked(f, e -> {
      throw new RuntimeException(e);
    });
  }

  static <T, E extends Exception> Supplier<T> toUnchecked(SupplierExceptionWrapper<T, E> f, Consumer<Exception> c) {
    return () -> {
      try {
        return f.supply();
      } catch (Exception e) {
        c.accept(e);
        return null;
      }
    };
  }
  
  T supply() throws E;
}

 

try-catch가 모든 코드에 박혀있는 게 싫다면 try-catch 안에서 실행시켜야 하는 로직 자체를 넘겨

마치 함수형인 듯 써보는 건 어떨까? 물론 난 사용하지 않는 방식이다, 그냥 재미로 만들어봤다

이 방식은 로직과 에러 처리를 분리할 수 있다는 점에 의의가 있을 것 같다, 잡기술이지만 SRP를 지켜내는 것 아닐까?

결론으로 생각의 전환을 해보면 다른 언어에는 Checked Exception이 없는 기능이니 자바에서만 신나게 쓸 수 있다는 것이다!

@Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class TryUtils {

  public static <T> void doTry(Consumer<T> consumer, T parameter) {
    try {
      consumer.accept(parameter);
    } catch (Exception e) {
      log.error("Exception : ", e);
    }
  }

  public static <T> Optional<T> doTry(Supplier<T> supplier) {
    try {
      return Optional.ofNullable(supplier.get());
    } catch (Exception e) {
      return Optional.empty();
    }
  }
}

 

'Java > Effective Java' 카테고리의 다른 글

[Item72] 표준을 사용하자  (0) 2023.06.18
[Item70] Checked Exception 금지  (0) 2022.11.01
[Item69] 예외 기반 반복  (2) 2022.09.25
[Item68] 컨벤션 따르기  (1) 2022.09.11
[Item67] 최적화는 나중에  (0) 2022.08.28
댓글
링크
글 보관함
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Total
Today
Yesterday