자바독(Javadoc)
- 소스코드 파일에서 자바독 주석이라는 특수한 형태로 기술된 설명을 API 문서로 변환해준다.
- Java 언어로 작성된 소스 코드에 대한 문서를 HTML 형식으로 생성하는 도구이다.
- 클래스, 인터페이스, 메소드, 필드 등에 대한 설명을 제공한다.
공개된 모든 클래스, 인터페이스, 메소드, 필드 선언에 문서화 주석을 달아야 한다.
- 직렬화할 수 있는 클래스라면 직렬화 형태(item 87)에 관해서도 작성해야 한다.
- 자바의 기본 생성자에는 문서화 주석을 작성할 수 없다.
- 따라서 공개 클래스는 절대 기본 생성자를 사용하면 안 된다.
- 유지 보수를 위해 비공개 클래스, 인터페이스, 생성자, 메소드, 필드에도 문서화 주석을 달아야 한다.
메소드용 문서화 주석에는 해당 메소드와 클라이언트 사이의 규약을 명료하게 기술해야 한다.
- 상속용으로 설계된 클래스(item 19)의 메소드가 아니라면 무엇을 하는지 기술해야 한다.
- 클라이언트가 해당 메소드를 호출하기 위한 전제조건(precondition)을 모두 나열해야 한다.
- 일반적으로 전제조건은 @throws 태그로 비검사 예외를 선언하여 암시적으로 기술한다.
- 비검사 예외 하나가 전제조건 하나와 연결되는 것이다.
- @param 태그를 이용해 그 조건에 영향받는 매개변수에 대해 기술할 수도 있다.
- 메소드가 성공적으로 수행된 후에 만족해야 하는 사후조건(postcondition)도 모두 나열해야 한다.
부작용도 문서화해야 한다.
- 부작용이란 사후조건으로 명확히 나타나지는 않지만 시스템으 상태에 어떠한 변화를 가져오는 것을 뜻한다.
- 예를 들어, 백그라운드 스레드를 시작시키는 메소드라면 이를 문서에 작성해야 한다.
문서화 태그
@param
- 메소드의 파라미터에 대한 정보를 작성해야 한다.
- 모든 매개변수에 작성해야 한다.
@return
- 메소드의 반환값을 설명하는 명사구를 작성한다. (산술 표현식을 작성하는 경우도 있다.)
- 반환 타입이 void가 아니라면 작성해야 한다.
- 코딩 표준에서 허락한다면 @return 태그의 설명이 메소드 설명과 같을 때 @return 태그를 생략해도 좋다.
@throws
- 발생할 수 있는 모든 예외에 작성해야 한다.(item 74)
- if로 시작해 해당 예외를 던지는 조건을 설명하는 절이 뒤따른다.
@code
: java 5
- 태그로 감싼 내용을 코드용 폰트로 렌더링한다.
- 태그로 감싼 내용에 포함된 HTML 요소나 다른 JavaDoc 태그를 무시한다.
- 여러 줄로 된 코드 예시를 넣으려면 <pre>{@code ...코드... }</pre> 형태로 쓰면 된다.
- 이렇게 하면 HTML의 탈출 메타문자를 쓰지 않아도 코드의 줄바꿈이 그대로 유지된다.
- 단, @ 기호에는 무조건 탈출 문자를 붙여야 하니 문서화 주석 안의 코드에서 애너테이션을 사용한다면 주의해야 한다.
@implSpec
: java 8
- 클래스를 상속용으로 설계할 때는 자기사용 패턴(item 15)에 대해서도 문서에 남겨 그 메소드를 올바르게 재정의하는 방법을 알려야 한다.
- 일반적인 문서화 주석은 해당 메소드와 클라이언트 사이의 관계를 설명하지만, @implSpec 주석은 해당 메소드와 하위 클래스 사이의 계약을 설명한다.
- 하위 클래스들이 그 메소드를 상속하거나 super 키워드를 이용해 호출할 때 그 메소드가 어떻게 동작하는지를 명확히 인지하고 사용하도록 해야 한다.
- -tag "implSpec:a:Implementation Requirements:" 스위치를 키지 않으면 @implSpec 태그를 무시한다.
@literal
: java 5
- <. >와 같은 HTML 마크업이나 자바독 태그를 무시하게 해준다.
- @code와 비슷하지만, 코드 폰트로 렌더링하지 않는다.
- "* A geometric series converges if {@literal |r| < 1}."처럼 사용할 수 있다.
- "A geometric series converges if |r| < 1"으로 변환된다.
예시 1 - BigInteger
/**
* Returns the element at the specified position in this list.
*
* <p>This method is <i>not</i> guaranteed to run in constant time.
* In some implementations it may run in time proportional to the element position.
* @param index index of the element to return
* @return the element at the specified position in this list
* @throws IndexOutOfBoundsException if the index is out of range
* ({@code index < 0 || index >= size()})
*/
E get(int index);
- @param, @return, @throws 태그의 설명에는 마침표를 붙히지 않는다.
- 문서화 주석 안의 HTML 요소들은 최종 HTML 문서에 반영된다.
예시 2 - @impleSepc 사용
/**
* Returns true if this collection is empty. // 요약 설명
*
* @implSpec This implementation returns {@code this.size() == 0}.
*
* @return true if this collection is empty
*/
public boolean isEmpty() {
return false;
}
요약 설명
- 각 문서화 주석의 첫 번째 문장은 해당 요소의 요약 설명으로 간주된다.
- 반드시 대상의 기능을 고유하게 기술해야 한다.
- 한 클래스(혹은 인터페이스) 안에서 요약 설명이 같은 멤버(혹은 생성자)가 둘 이상이면 안 된다.
- 다중정의된 메소드가 있다면 특히 주의해야 한다.
- 첫 번째 . 기호가 나타나기 까지의 문장을 첫 번째 문장으로 간주한다.
- 의도치 않은 마침표를 포함한 텍스트는 {@literal}로 감싸준다.
- 자바 10부터는 {@summary}라는 요약 설명 전용 태그가 추가되어, 깔끔하게 처리할 수 있다.
- 메소드와 생성자의 요약 설명은 해당 메소드와 생성자의 동작을 설명하는 (주어가 없는) 동사구여야 한다.
- 2인칭 문장이 아닌 3인칭 문장으로 작성해야 한다.(한글은 예외다)
ArrayList(int initialCapacity): Constructs an empty list with the specified initail capacity
Collection.size(): Returns the number of elements in this collection.
- 클래스, 인터페이스, 필드의 요약 설명은 대상을 설명하는 명사절이어야 한다.
- 클래스와 인터페이스의 대상은 그 인스턴스이고, 필드의 대상은 필드 자신이다.
Instant: An instantaneous point on the time-line.
Math.PI: The double value that is closer than any other to pi, the ratio of the circumference of a circle to its diamter.
색인 기능
@index
: 자바 9 이후
- 클래스, 메소드, 필드 같은 API 요소의 색인은 자동으로 만들어진다.
- 추가로 {@index} 태그를 사용해 API에서 중요한 용어를 추가로 색인할 수 있다.
This method compiles with the {@index IEEE 754} standard.
제네릭 타입/제네릭 메소드의 주석
- 제네릭 타입이나 제네릭 메소드를 문서화할 때는 모든 타입 매개변수에 주석을 달아야 한다.
/*
* An object that maps keys to values. A map cannot contain duplicate keys;
* each key can map to at most one value.
*
* @param <K> the type of keys maintained by this map
* @param <V> the type of mapped values
*/
public interface Map<K, V> {
열거 타입의 주석
- 열거 타입을 문서화할 때는 상수들에도 주석을 달아야 한다.
- 열거 타입 자체와 그 열거 타입의 public도 포함이다.
/**
* An instrument section of a symphony orchestra
*/
public enum OrchestraSection {
/** WoodWinds, such as flute, clarinet and oboe */
WOODWIND,
/** Brass instruments, such as french horn and trumper */
BRASS,
/** Percussion instruments, such as timpani, cymbals */
PERCUSSION,
/** Stringed instruments, such as violin and cello */
STRING
}
애너테이션 타입의 주석
- 애너테이션 타입을 문서화할 때는 멤버들에도 모두 주석을 달아야 한다.
- 필드 설명은 명사구로 한다.
- 애너테이션 타입의 요약 설명은 프로그램 요소에 이 애너테이션을 단다는 것이 어떤 의미인지를 설명하는 동사구로 한다.
/**
* Indicates that the annotated method is a test method that
* must throw the designated exception to pass
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ExceptionTest {
/**
* The exception that the annotated test method must throw
* in order to pass. (The test is permitted to throw any subtype
* of the type described by this class object.)
*/
Class<? extends Throwable> value();
}
패키지를 설명하는 문서화 주석은 package-info.java 파일에 작성한다.
- 패키지 선언을 반드시 포함해야 하며 패키지 선언 관련 애너테이션을 추가로 포함할 수도 있다.
- 모듈 시스템(item 15)을 사용한다면 module-info.java에 모듈 관련 설명을 작성하면 된다.
클래스 혹은 정적 메소드가 스레드 안전하든 그렇지 않든,
스레드 안전 수준을 반드시 API 설명에 포함해야 한다.(item 82)
- 직렬화할 수 있는 클래스라면 직렬화 형태도 API 설명에 기술해야 한다.(item 87)
Javadoc은 메소드 주석을 상속시킬 수 있다.
- 문서화 주석이 없는 API 요소를 발견하면 자바독이 가장 가까운 문서화 주석을 찾아준다.
- 상위 클래스보다 그 클래스가 구현한 인터페이스를 먼저 찾는다.
- {@inheritDoc} 태그를 사용해 상위 타입의 문서화 주석 일부를 상속할 수 있다.
- 클래스는 자신이 구현한 인터페이스의 문서화 주석을 재사용할 수 있다.
- 유사한 문서화 주석을 유지보수하는 부담은 줄지만, 사용하기 까다롭고 제약이 있다.
기타 주의사항
- 여러 클래스가 상호작용하는 복잡한 API라면 문서화 주석 외에도 전체 아키텍처를 설명하는 별도의 설명이 필요한 경우가 있다.
- 이런 설명 문서가 있다면 관련 클래스나 패키지의 문서화 주석에서 그 문서의 링크를 제공하면 좋다.