Java
[Java] JavaDoc
아몬드맛빼빼로
2025. 5. 5. 15:05
반응형

/** What is */
가끔씩 Github에서 방랑하며 코드를 읽다 보면 /**로 시작하여 */로 감싸지는 블럭주석들을 볼 수 있다. Java의 블록 주석은 /* */ 이렇게만 감싸도 되는데 왜 저런 주석들을 쓰는 걸까?
이는 JavaDoc 주석으로 일반 주석과는 달리 여러 정보를 체계적으로 전달할 수 있다.
기능...?
/**
* 도메인 객체와 JPA 엔티티 간의 양방향 매핑을 정의하는 제네릭 인터페이스입니다.
* <p>이 인터페이스는 매퍼 구현체에서 공통적으로 사용하는 구조를 추상화하며,
* 도메인 모델과 영속성 계층의 엔티티 간 변환 로직을 표준화합니다.
* @param <ENTITY> 변환 대상이 되는 JPA 엔티티 타입
* @param <DOMAIN> 변환 대상이 되는 도메인 객체 타입
* @author snowykte0426
*/
public interface GenericMapper<ENTITY, DOMAIN> {
ENTITY toEntity(DOMAIN domain);
DOMAIN toDomain(ENTITY entity);
}
이런식으로 주석이 작성되어 있다면 IDE에서 이를 인식하여 툴팁으로 보여준다

문법
기본적으로 /**으로 주석 블록을 열고 */으로 블럭을 닫는다.
기본적인 작동원리가 JavaDoc 툴이 주석을 읽어 HTML 문서로 만들어주는 것이기 때문에 <ul>, <li>, <p> 등의 HTML 태그 일부도 사용 가능하다.
JavaDoc만의 기능으로 여러 태그들이 있는데 아래와 같다.
태그 | 용도 | 설명 | 사용위치 | 예시 |
@author | 작성자 정보 | 클래스/인터페이스 작성자 이름 | 클래스/인터페이스 | @author 홍길동 |
@version | 버전 정보 | 클래스/인터페이스 버전 명시 | 클래스/인터페이스 | @version 1.0.0 |
@since | 버전 도입 정보 | 해당 요소가 처음 도입된 버전 | 클래스/인터페이스/메서드 등 | @since 1.5 |
@param | 매개변수 설명 | 메서드의 매개변수를 설명 | 메서드 | @param name 사용자 이름 |
@return | 반환값 설명 | 메서드의 반환값 설명 | 메서드 | @return 계산 결과 |
@throws / @exception | 예외 설명 | 예외 발생 가능성을 문서화 | 메서드 | @throws IOException 파일을 찾을 수 없음 |
@deprecated | 사용 중단 알림 | 더 이상 사용하지 말라는 의미 | 클래스/인터페이스/메서드 등 | @deprecated 대신 newMethod() 사용 |
@see | 관련 황목 참조 | 관련된 클래스/메서/링크 등 참조 | 어디든 가능 | @see java.util.List |
@link | 인라인 링크 | 설명안에 클래스/메서드 등 링크 삽입 | 설명 중간 | {@link java.util.Map} |
@linkplain | 링크 (텍스트로 표시) | @link와 같지만 강조효과 없음 | 설명 중간 | {@linkplain java.util.Map} |
@code | 코드 강조 | 코드로 보여줌(고정폭 글꼴) | 설명 중간 | {@code a + b} |
@literal | 특수문자 그대로 표시 | HTML 이스케이프 없이 출력 | 설명 중간 | {@literal < > &} |
@inheritDoc | 문서 상속 | 상위 클래스/인터페이스의 설명 상속 | 오버라이드된 메서드 | {@inheritDoc} |
@serial | 직렬화 설명 | 직렬화 필드 설명 | 필드 | @serial 사용자 이름 |
@serialField | 직렬화 필드 설명 | ObjectStreamField 배열용 | 클래스 | @serialField name 사용자 이름 |
@serialData | 직렬화 데이터 설명 | writeObject 메서드용 | 메서드 | @serialData 사용자 데이터가 포함됨 |
@value | 상수값 삽입 | 상수 필드 값을 문서에 삽입 | 설명 중간 | {@value #MY_CONSTANT} |
더보기
ObjectStreamField와 writeObject?
java.io.ObjectStreamField 클래스는 직렬화(객체를 바이트 스트림으로 변환하는 것) 시 어떤 필드를 포함시킬지 정의하는 클래스이고 writeObject는 객체를 직접 커스터마이징하여 직렬화할 수 있는 메서드로 기본 직렬화 동작을 제어하거나 수정을 원할 때 사용 가능하다.
적용 예시
import java.io.*;
/**
* 사용자의 정보를 나타내는 클래스
* 사용자 이름만 직렬화 대상이 되며, 비밀번호는 직렬화되지 않는다.
*
* @author 홍길동
* @version 1.0
* @since 2025-05-05
*/
public class User implements Serializable {
/**
* 직렬화에 포함될 필드를 명시한다.
* 오직 username 필드만 직렬화
*
* @serialField username String 사용자 이름
*/
private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("username", String.class)
};
private String username;
private transient String password; // 직렬화되지 않음
public User(String username, String password) {
this.username = username;
this.password = password;
}
/**
* 사용자 이름을 반환한다.
*
* @return 사용자 이름
*/
public String getUsername() {
return username;
}
/**
* 사용자 비밀번호를 반환한다. (직렬화되지 않음)
*
* @return 사용자 비밀번호
*/
public String getPassword() {
return password;
}
/**
* 사용자 이름만 직렬화하도록 커스터마이징된 writeObject 메서드
*
* @param out ObjectOutputStream 객체 출력 스트림
* @throws IOException 직렬화 중 오류가 발생한 경우
* @serialData 사용자 이름만 포함
*/
private void writeObject(ObjectOutputStream out) throws IOException {
ObjectOutputStream.PutField fields = out.putFields();
fields.put("username", username);
out.writeFields();
}
/**
* 사용자 이름만 역직렬화하도록 커스터마이징된 readObject 메서드이다.
*
* @param in ObjectInputStream 객체 입력 스트림
* @throws IOException 입출력 오류 발생 시
* @throws ClassNotFoundException 클래스 로딩 오류 발생 시
*/
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
ObjectInputStream.GetField fields = in.readFields();
username = (String) fields.get("username", null);
password = null; // 비밀번호는 복원되지 않음
}
}
정리
JavaDoc는 손쉽고 체계적인 문서화를 도와주는 훌륭한 도구로 다른 개발자로 하여금 코드를 바로바로 해석하며 양질의 참고자료를 제공할 수 있어 일정한 형식으로 잘 활용한다면 팀의 생산성을 높여줄 수 있는 훌륭한 도구이다. 그러나 일관성 없거나 작은 프로젝트에 마구잡이로 도입하면 코드에 작성하는 방식이니만큼 오히려 코드가 더러워 보이는 역효과를 유발할 수 있으니 잘 판단하여 도입하자