Reference/Effective-Java

[Effective-Java] Chapter10 #74. 메서드가 던지는 모든 예외를 문서화하라

나죽못고나강뿐 2023. 8. 2. 10:44
1️⃣ 검사 예외는 항상 따로따로 선언하고, 각 예외가 발생하는 상황을 @throws 태그로 정확히 문서화하라
  • 공통 상위 클래스(Exception, Throwable)로 뭉뚱그려 선언하는 일은 삼가하라
    • 메서드 사용자에게 대처할 힌트를 주지 못한다.
    • 같은 맥락에서 발생할 여지가 있는 다른 예외까지 삼켜버릴 수 있다.
    • main 메서드는 오직 JVM만이 호출하므로 Exception을 던져도 괜찮은 유일한 예다.
  • 비검사 예외도 검사 예외처럼 문서화 해두면 좋다.
    • 자신이 일으킬 수 있는 오류들을 알림으로써 프로그래머가 해당 오류가 나지 않도록 코딩하게 돕는다.
    • 사실상 해당 메서드를 성공적으로 수행하기 위한 전제조건이 된다.
    • 인터페이스 메서드의 경우 해당 조건이 일반 규약에 속하게 되어, 모든 구현체가 일관되게 동작하도록 돕는다.
    • 물론 외부 클래스 수정으로 인한 새로운 비검사 예외 전파 등의 예기치 못한 경우로 모두 문서화하는 것은 힘든 일이다.

 

2️⃣ 예외를 각각 @throws 태그로 문서화 하되, 비검사 예외는 메서드 선언의 throws 목록에 넣지 마라
/**
 * @throws SQLException SQL 이 잘못된 경우
 * @throws ClassNotFoundException 지정한 경로에 클래스파일이 존재하지 않는경우.
 * @throws NullPointerException 지정한 요소에 null 이 들어오는 경우
 */
public void foo() throws SQLException, ClassNotFoundException{
    ...
}
  • 검사냐 비검사냐에 따라 API 사용자가 해야할 일이 달라지므로 확실히 구분하라.
  • Java docs 유틸리티는 throws절, @throws 태그 모두 명시한 (검사)예외와 @throws 태그에만 명시한 예외를 시각적으로 구분해준다. 

 

3️⃣ 한 클래스의 많은 메서드가 같은 이유로 같은 예외를 던진다면 클래스 설명에 추가해도 된다.
public class Foo {
    /**
     * @throws SQLException SQL 이 잘못된 경우
     * @throws ClassNotFoundException 지정한 경로에 클래스파일이 존재하지 않는경우.
     * @throws NullPointerException 지정한 요소에 null 이 들어오는 경우
     */
    public void fooMethod1() throws SQLException,ClassNotFoundException{ ... }
    
    /**
     * @throws NullPointerException 지정한 요소에 null 이 들어오는 경우
     */
    public void fooMethod2() throws IOException{ ... }
}
/**
 * <p> {@code NullPointerException} 지정한 요소에 null 이 들어오는 경우 발생합니다.</p> 
 */
public class Foo {
    /**
     * @throws SQLException SQL 이 잘못된 경우
     * @throws ClassNotFoundException 지정한 경로에 클래스파일이 존재하지 않는경우.
     */
    public void fooMethod1() throws SQLException,ClassNotFoundException{ ... }
    
    public void fooMethod2() throws IOException{ ... }
}