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

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

🔹 핵심 요약

✅ 메서드가 던질 가능성이 있는 모든 예외를 문서화하라 ✅ 검사 예외(checked exception)는 항상 개별적으로 @throws 태그로 문서화 ✅ 비검사 예외(unchecked exception)도 문서화하면 API 사용성이 크게 개선됨 ✅ 한 클래스의 많은 메서드가 같은 이유로 같은 예외를 던진다면 클래스 설명에 추가 가능


📚 필수 개념 정리

🧩 자바의 예외 유형

특성
검사 예외(Checked Exception)
비검사 예외(Unchecked Exception)

상속 계층

Exception의 하위 클래스

RuntimeException의 하위 클래스

처리 의무

반드시 처리(try-catch, throws)

처리 선택적

컴파일 확인

컴파일러가 확인

컴파일러가 확인하지 않음

예시

IOException, SQLException

NullPointerException, IndexOutOfBoundsException

🔍 예외 문서화 방법

/**
 * 지정된 URL의 내용을 가져와 문자열로 반환합니다.
 *
 * @param url 내용을 가져올 URL
 * @return URL의 내용을 나타내는 문자열
 * @throws IOException URL에서 데이터를 읽는 중 I/O 오류가 발생한 경우
 * @throws IllegalArgumentException URL이 null이거나 유효하지 않은 형식인 경우
 */
public static String fetchContent(String url) throws IOException {
    // 메서드 구현
}

🚨 잘못된 예외 문서화와 올바른 문서화

예외가 명시되지 않은 문서화

/**
 * 파일에서 데이터를 읽어 처리합니다.
 *
 * @param filePath 읽을 파일의 경로
 * @return 처리된 데이터
 */
public String processFile(String filePath) throws IOException {
    // 여기서 NullPointerException, IllegalArgumentException이
    // 발생할 수 있지만 문서화되지 않음
    // ...
}

올바른 예외 문서화

/**
 * 파일에서 데이터를 읽어 처리합니다.
 *
 * @param filePath 읽을 파일의 경로
 * @return 처리된 데이터
 * @throws NullPointerException filePath가 null인 경우
 * @throws IllegalArgumentException filePath가 빈 문자열인 경우
 * @throws IOException 파일을 찾을 수 없거나, 읽기 권한이 없는 경우
 */
public String processFile(String filePath) throws IOException {
    // 구현...
}

💡 클래스 수준의 예외 문서화

여러 메서드가 동일한 이유로 같은 예외를 던질 때 클래스 수준에서 문서화할 수 있습니다.

/**
 * 파일 시스템에서 작업을 수행하는 유틸리티 클래스입니다.
 *
 * <p>이 클래스의 모든 메서드는 다음 예외를 던질 수 있습니다:</p>
 * <ul>
 *   <li>{@link NullPointerException} - 메서드 인수로 null이 전달된 경우</li>
 *   <li>{@link SecurityException} - 보안 관리자가 파일 작업을 거부한 경우</li>
 * </ul>
 */
public class FileUtils {
    // 메서드 구현...
}

🧠 예외 문서화 전략

🌟 검사 예외(Checked Exception)

  • 문서화 필수: 검사 예외는 반드시 @throws 태그로 문서화해야 합니다. 이 예외는 반드시 처리하거나 선언해야 하므로, 사용자가 예외를 예상하고 적절히 대응할 수 있도록 설명을 추가해야 합니다.

  • 메서드 선언부: 메서드에서 발생할 수 있는 검사 예외를 throws 절에 명시합니다. 이는 예외가 발생할 수 있음을 명확히 알리는 역할을 합니다.

  • 상황과 조건 설명: 예외가 발생할 수 있는 특정 상황을 구체적으로 설명합니다. 예를 들어, 데이터베이스 쿼리 실패, 파일 입출력 오류 등이 있습니다.

/**
 * @throws SQLException 데이터베이스 연결 오류 또는 쿼리 실행 중 오류가 발생한 경우
 */

🎯 비검사 예외(Unchecked Exception)

  • 메서드 선언부: 비검사 예외는 throws 절에 포함하지 않으며, 메서드 선언부에서는 언급하지 않습니다. 대신 메서드 내에서 발생할 수 있는 예외에 대해 문서화만 하면 됩니다.

  • 예외 발생 가능성 경고: 비검사 예외는 사용자가 잘못된 입력을 했을 때나 의도하지 않은 상황에서 발생할 수 있습니다. 이러한 예외들이 무엇인지 경고하고, 예외를 피할 수 있는 방법을 안내하는 것이 좋습니다.

/**
 * @throws ArithmeticException divisor가 0인 경우
 */

📊 예외 문서화 Best 사례

  1. 구체적인 조건 명시 - 예외 발생 조건을 명확히 설명

  2. 관련 매개변수 표시 - 어떤 매개변수가 예외와 관련되는지 명시

  3. 일관된 형식 유지 - 비슷한 예외는 비슷한 형식으로 문서화

  4. 복구 가능성 힌트 제공 - 가능하면 예외 복구 방법 제시

/**
 * @throws IndexOutOfBoundsException 인덱스가 범위를 벗어난 경우
 *         ({@code index < 0 || index >= size()})
 */

🌐 자바 라이브러리의 예외 문서화 사례

Java의 표준 라이브러리는 예외 문서화의 좋은 예시를 제공합니다:

/**
 * ArrayList의 get 메서드 문서화
 *
 * @param index 가져올 요소의 인덱스
 * @return 지정된 위치의 요소
 * @throws IndexOutOfBoundsException 인덱스가 범위를 벗어난 경우
 *         ({@code index < 0 || index >= size()})
 */
public E get(int index) {
    // 구현...
}

🎯 결론

📍 메서드가 던질 가능성이 있는 모든 예외를 문서화하라

📍 검사 예외는 항상 @throws 태그로 개별적으로 문서화하라

📍 비검사 예외도 문서화하면 API 사용성이 크게 개선된다

📍 정확한 예외 발생 조건을 명시하여 API 사용자가 예외 상황을 피할 수 있게 하라


💭 느낀 점

💡좋은 API 문서화의 핵심은 사용자가 해당 API를 어떻게 사용해야 하는지, 어떤 예외 상황이 발생할 수 있는지 명확히 이해할 수 있도록 하는 것이라는 것을 다시금 느꼈습니다

💡 단순히 예외를 나열하는 것이 아니라, 발생 조건을 구체적으로 설명하는 것이 사용자에게 더 큰 도움이 된다는 것을 배웠습니다

💡 자바의 표준 라이브러리와 유명 프레임워크들의 문서화 방식을 살펴보면 예외 처리의 중요성과 문서화 전략을 더 깊이 이해할 수 있었습니다

Last updated