[이펙티브자바] 10장 예외(item69-77) 정리

예니·2022년 9월 29일
0

이펙티브자바

목록 보기
9/11
post-thumbnail

아이템 69. 예외는 진짜 예외 상황에만 사용하라

  • 예외를 제어 흐름용으로 사용하지 말자
  • 예외를 제어 흐름에 사용하는 것은 표준 관용구보다 훨씬 느리다
  • 예외를 제어 흐름에 사용하면, 흐름 제어에 사용한 예외가 버그를 숨겨 디버깅이 어려워진다
  • 예외는 오직 예외 처리 용도로만 사용하자

아이템 70. 복구할 수 있는 상황에는 검사 예외를, 프로그래밍 오류에는 런타임 예외를 사용하라

  • 호출하는 쪽에서 복구하리라 생각되는 경우엔 검사 예외를 사용
    catch로 잡아 처리하거나, throws를 사용하여 더 바깥으로 전파하도록 강제
    검사 예외라면 복구하는 법을 알려주는 메서드도 같이 제공하자
  • 프로그래밍 오류를 나타낼 때는 런타임 예외를 사용
    클라이언트가 해당 API의 명세를 지키지 않았을 때 사용
  • 복구 가능하다고 믿으면 검사 예외, 그렇지 않으면 런타임 예외 사용하자
    확신이 없어도 런타임 예외
  • 직접 구현하는 비검사 throwable의 경우, RuntimeException의 하위 클래스여야 한다
  • 이상한 것 좀 만들지 말자

아이템 71. 필요 없는 검사 예외 사용은 피하라

  • 검사 예외는 api를 불편하게 만들 수 있다
    검사 예외를 던지는 메서드는 스트림 안에서 직접 사용할 수 없음
  • 검사 예외를 회피하는 방법
    1. 비검사 예외 사용
    2. Optional 반환

    검사 예외 대신 빈 옵셔널 반환. 예외가 발생한 이유를 제공할 수 없음
    3. 메서드 분리
    검사 예외를 던지는 메서드 → 상태 검사 메서드 + 비검사 예외를 던지는 메서드
    상태 검사 메서드는 외부 동기화 없이 여러 스레드가 동시에 접근할 수 있거나, 외부 요인에 의해 상태가 변할 수 있다면 사용하지 않는 것이 좋다 (아이템 69)

아이템 72. 표준 예외를 사용하라

  • 표준 예외를 쓰자.
    모두에게 쉽게 다가온다. 읽기 쉽다.
    예외 클래스가 적을수록 메모리 사용량도 줄고, 클래스를 적재하는 시간도 적게 든다.
  • IllegalArgumentException : 허용하지 않는 값이 인수로 건네졌을 때
  • IllegalStateException : 객체가 메서드를 수행하기에 적절하지 않은 상태일 때
  • NullPointerException : null을 허용하지 않는 메서드에 null을 건넸을 때
  • IndexOutOfBoundsException : 인덱스가 범위를 넘었을 때
  • ConcurrentModificationException : 허용하지 않는 동시 수정
  • UnsupportedOperationException : 호출한 메서드를 지원하지 않을 때
  • Exception, RuntimeException, Throwable, Error는 직접 재사용하지 말자.
    추상 클래스라고 생각하자. 안정적으로 쓸 수 없다.
  • 진짜 필요한 거 아니면 커스텀 예외는 만들지 말자
  • 인수값이 무엇이었든 실패했을거라면 IllegalStateException, 그게 아니면 IllegalArgumentException

아이템 73. 추상화 수준에 맞는 예외를 던지라

  • 상위 계층에서는 저수준 예외를 잡아 자신의 추상화 수준에 맞는 예외로 바꿔 던져야 한다. (예외 번역)
    그렇지 않으면, 내부 구현 방식을 드러내어 윗 레벨 API를 오염시킨다. 구현 방식을 바꾸면 다른 예외가 튀어나와 기존 클라이언트 프로그램을 깨지게 할 수 있다.
  • 예외 번역 시, 저수준 예외가 디버깅에 도움이 된다면 저수준 예외를 고수준 예외에 같이 실어보내는 예외 연쇄를 사용하자.
    대부분의 표준 예외는 예외 연쇄용 생성자를 갖추고 있다.
  • 그렇다고 예외 번역을 남용하지는 말자.
    1. 저수준 메서드를 반드시 성공하게 해서 아래 계층에서 예외가 발생하지 않도록 (ex. 매개변수 넘기기 전에 미리 검사)
    2. 적절히 로깅하여 예외 전파없이 적절한 조치를 취할 수 있도록

아이템 74. 메서드가 던지는 모든 예외를 문서화하라

  • 검사 예외는 따로따로 선언, 모든 예외는 자바독 @throws로 정확히 문서화하자
    공통 상위 클래스 하나로 뭉뚱그려버리면 안된다. JVM만이 호출할 수 있는 main 메서드는 예외
  • 비검사 예외는 메서드 선언의 throws 목록에 넣지 말자
  • 한 클래스 안의 많은 메서드가 같은 이유로 같은 예외를 던진다면, 클래스 설명에 추가할 수도 있다

아이템 75. 예외의 상세 메시지에 실패 관련 정보를 담으라

  • 예외의 toString 메서드에 실패 원인에 관한 정보를 가능한 많이 담자
  • 실패 순간을 포착하려면 발생한 예외에 관여된 모든 매개변수, 필드의 값을 실패 메세지에 담아야 한다
  • 예외의 상세 메세지와 사용자에게 보여줄 오류 메세지를 혼동하지 말자
    사용자에게 보여주는 것은 친절하게, 번역까지.
    예외 메세지는 필요한 정보를.

아이템 76. 가능한 한 실패 원자적으로 만들라

  • 호출된 메서드가 실패하더라도 해당 객체는 메서드 호출 전 상태를 유지해야 한다.
  • 메서드를 실패 원자적으로 만드는 방법
    1. 불변 객체로 설계
    불변 객체는 태생이 실패 원자적
    가변 객체 사용한다면 작업 수행 전 매개변수 유효성 검사
    2. 실패할 가능성이 있는 모든 코드를 상태를 바꾸는 코드보다 앞에 배치
    3. 객체의 임시 복사본에서 작업 수행 → 작업 성공하면 원래 객체와 교체
    4. 작업 도중 발생하는 실패를 가로채는 복구 코드 작성
  • Error는 복구할 수 없으므로 실패 원자적으로 만들지 않아도 됨
  • 항상 실패 원자적으로 만들어야하는 것은 아님
    실패 원자성을 달성하기 위한 비용이나 복잡도가 아주 크다면..

아이템 77. 예외를 무시하지 말라

  • catch 블록을 비워두지 말자
  • 예외를 무시하기로 했다면, catch 블록 안에 주석 남기고, 예외 변수의 이름도 ignored로 바꾸자
  • 무시하지 않고 바깥으로 전파되게만 둬도 최소한 디버깅 정보를 남긴 채 신속히 중단되게 할 수 있다

0개의 댓글