10장. 예외 - GOAL

예외를 제대로 활용한다면 프로그램의 가독성, 신뢰성, 유지보수성이 높아진다.
그러나 잘못 사용하면 반대의 효과만 나타난다.
예외를 효과적으로 활용하는 방법을 습득하자.

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

메서드가 던지는 예외는 그 메서드를 올바로 사용하는데 아주 중요한 정보다. 따라서 각 메서드가 던지는 예외 하나하나를 문서화하는 데 충분한 시간을 쏟아야 한다.

검사 예외 문서화

  • 검사 예외는 항상 따로따로 선언하고, 각 예외가 발생하는 상황을 자바독의 @throws 태그를 사용하여 정확히 문서화하자.
  • 공통 상위 클래스 하나로 뭉뚱그려 선언하는 일은 삼가자.
    • 메서드가 Exception이나 Throwable을 던진다고 선언해서는 안 된다.
    • 메서드 사용자에게 각 예외에 대처할 수 있는 힌트를 주지 못할뿐더러, 같은 맥락에서 발생할 여지가 있는 다른 예외들까지 삼켜버릴 수 있어 API 사용성을 크게 떨어뜨린다.
    • 예외로, main은 오직 JVM만이 호출하므로 Exception을 던지도록 선언해도 괜찮다.
/**
 * blah blah...
 *
 * @param fileName
 * @throws IOException
 */
public void someMethod(String fileName) {
    try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
    } catch (IOException e) {
        // exception handling
    }
}

비검사 예외 문서화

비검사 예외는 일반적으로 프로그래밍 오류를 뜻하는데, 자신이 일으킬 수 있는 오류들이 무엇인지 알려주면 프로그래머는 자연스럽게 해당 오류가 나지 않도록 코딩하게 된다.
public 메서드라면 필요한 전제조건을 문서화해야 하며, 그 수단으로 가장 좋은 것이 바로 비검사 예외들을 문서화하는 것이다.


  • 메서드가 던질 수 있는 예외를 각각 @throws 태그로 문서화하되, 비검사 예외는 메서드 선언의 throws 목록에 넣지 말자.
  • javadoc 유틸리티에서는 메서드 선언의 throws 절에 등장하고 메서드 주석의 @throws 태그에도 명시된 예외와 @throws 태그에만 명시된 예외를 시각적으로 구분하기 때문이다.
  • 검사냐 비검사냐에 따라 API 사용자가 해야할 일이 달라지므로, 이 둘을 확실히 구분해주는 게 좋다.
/**
 * blah blah...
 *
 * @param divisor
 * @throws ArithmeticException
 *     Exception may occur when divisor is zero    
 */
public int someMethod(int divisor) throws ArithmeticException {
    // throws 선언에는 제외하는 것을 권장한다.
}
  • 한 클래스에 정의된 많은 메서드가 같은 이유로 같은 예외를 던진다면, 그 예외를 (각각의 메서드가 아닌) 클래스 설명에 추가하는 방법도 있다.
/**
 * blah... blah...
 *
 * @throws NullPointerException
 *     All methods throw an exception if the argument is null.
 */
public class TestClass {

    /**
     * @param paramObj
     */
    public void someMethod1(Object paramObj) {
        if(paramObj == null) {
            throw new NullPointerException();
        }
    }

    /**
     * @param paramObj
     */
    public void someMethod2(Object paramObj) {
        if(paramObj == null) {
            throw new NullPointerException();
        }
    }
}

결론

메서드가 던질 가능성이 있는 모든 예외를 문서화하라.
자바독의 @throws 태그를 사용하면 된다. 검사 예외만 메서드 선언의 throws 문에 일일이 선언하고, 비검사 예외는 메서드 선언에는 기입하지 말자. 발생 가능한 문서로 남기지 않으면 다른 사람이 그 클래스나 인터페이스를 효과적으로 사용하기 어렵거나 심지어 불가능할 수도 있다.

예시 참조

https://madplay.github.io/post/document-all-exceptions-thrown-by-each-method