Java

[Java] JavaDoc

아몬드맛빼빼로 2025. 5. 5. 15:05
반응형
가장 현실적인 대안: 4단계 JavaDoc 도입

/** 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에서 이를 인식하여 툴팁으로 보여준다

IntelliJ IDEA

 

문법

기본적으로 /**으로 주석 블록을 열고 */으로 블럭을 닫는다.
기본적인 작동원리가 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}
더보기

ObjectStreamFieldwriteObject?

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는 손쉽고 체계적인 문서화를 도와주는 훌륭한 도구로 다른 개발자로 하여금 코드를 바로바로 해석하며 양질의 참고자료를 제공할 수 있어 일정한 형식으로 잘 활용한다면 팀의 생산성을 높여줄 수 있는 훌륭한 도구이다. 그러나 일관성 없거나 작은 프로젝트에 마구잡이로 도입하면 코드에 작성하는 방식이니만큼 오히려 코드가 더러워 보이는 역효과를 유발할 수 있으니 잘 판단하여 도입하자