Effective Java - Chapter 10

4 분 소요

Effective Java

[Effective Java 3/E] 10장 예외

Item 69. 예외는 진짜 예외 상황에만 사용하라

  • 예외를 사용한 쪽이 표준 관용구보다 훨씬 느리다.
  • 예외는 오직 예외 상황에서만 써야 하지, 일상적인 제어 흐름용으로 쓰여선 안 된다.
  • 되도록이면 클라이언트가 정상적인 제어 흐름에서 예외를 사용할 일이 없게 해야 한다. ‘상태 검사 메서드’를 쓰자.

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

  • 검사 예외(checked exception) : 호출하는 쪽에서 복구할 수 있을 때
  • 런타임 예외(unchecked exception-RuntimeException): 프로그래밍 오류
  • 에러(unchecked exception-Error)
    unchecked exception은 복구가 불가능하거나 득보다 실이 많으니 복구 하지 말고 문제를 먼저 찾자.

Item 71. 필요 없는 검사 예외 사용은 피하라

  • 검사 예외는 발생한 문제를 프로그래머가 처리하여 안전성을 높이게끔 해준다.
  • 검사 예외가 하나뿐이라면 스트림에 사용하지 못하는 등 단점이 있기 때문에 그 경우에는 회피 방법을 사용하면 좋다.
  • 회피 방법으로 옵셔널을 반환하여 예외를 피하는 경우가 있다.

Item 72. 표준 예외를 사용하라

널리 재사용되는 표준 예외

  • IllegalArgumentException : 허용되지 않는 값이 인수로 건네졌을 때
  • IllegalStateException : 객체가 메서드를 수행하기에 적절하지 않은 상태일 때
  • NullPointerException: null을 허용하지 않는 메서드에 null을 건넸을 때
  • IndexOutOfBoundsException: 인덱스가 범위를 넘어섰을 때
  • ConcurrentModificationException: 허용하지 않는 동시 수정이 발견됐을 때
  • UnsupportedOperationException: 호출한 메서드를 지원하지 않을 때

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

예외 번역 Exception translation

  • 상위 계층에서는 저수준 예외를 잡아 자신의 추상화 수준에 맞는 예외로 바꾸어 던져야 한다.
  • 수행하려는 일과 관련 없어 보이는 예외가 발생하는 것을 피할 수 있다.
try{
...
} catch(LowerLevelException e){ // 저수준 예외를 catch해서
  throw new HigherLevelException(...); // 자신의 수준에 맞는 예외로 바꾼다.
}

List 인터페이스의 get 메서드에 활용할 수 있다.

예외 연쇄 Exception chaining

  • 문제의 근본 원인인 저수준 예외를 고수준 예외에 실어 보내는 방식이다.
  • 고수준 예외 생성자의 인자로 저수준 예외를 넣는다.
try{
...
} catch(LowerLevelException e){
  throw new HigherLevelException(e);
}

Throwable의 initCause 메서드로 문제의 원인을 알 수 있다.

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

@throws 태그

  • Checked Exception은 항상 따로 @throws 태그를 사용해서 문서화한다.
  • main 메서드의 throws는 예외다. JVM만이 호출할 수 있기 때문.
  • 비검사 예외(RuntimeException, Error)도 문서화 해놓는 것이 좋다. 단, 메서드 선언의 throws 목록에는 넣지 않는다.

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

발생한 예외에 관여된 모든 매개변수와 필드의 값을 실패 메시지에 담아야 한다.

public IndexOutOfBoundsException(int lowerBound, int upperBound, int index){
  super(String.format("최솟값: %d ... );
}

Item 76. 가능한 한 실패 원자적으로 만들라

호출된 메서드가 실패하더라도 해당 객체는 메서드 호출 전 상태를 유지해야 한다.

failure-atomic으로 만드는 방법

  • 불변 객체로 설계한다.
  • 작업 수행에 앞서 매개변수의 유효성을 검사한다.
  • 객체의 임시 복사본에서 작업을 수행한 다음, 작업이 성공적으로 완료되면 원래 객체와 교체한다.
  • 작업 도중 발생하는 실패를 가로채는 복구 코드를 작성하여 작업 전 상태로 되돌린다.

Item 77. 예외를 무시하지 말라

  • catch 블록을 비워두면 예외가 존재할 이유가 없어진다.
  • 예외를 무시하기로 했다면 catch 블록 안에 그렇게 결정한 이유를 주석으로 남기고 예외 변수의 이름도 ignored로 바꿔놓도록 하자.

댓글남기기