Skip to content

Item56. API 문서화 주석 #32

@daminzzi

Description

@daminzzi

서론

Item56은 API 문서화 주석을 작성할 때의 주의사항에 대해서 이야기하고 있다. 주요 주석 태그와 실제 예시를 통한 그 활용법에 대해서 정리해보려고 한다.

API문서를 사람이 직접 작성하게 되면 코드 변경 등의 수정이 발생했을 때 하나하나 수정해야 한다는 불편함이 있는데, 자바에서는 JavaDoc 이 이를 해결해주고 있다. 책에서 언급한 사이트 문서화 주석 작성법(How to Write Doc Comments) 에서 기본적인 태그(java 4 미만)에 대해서 언급하고 있지만, java5의 @literal, @code, java8의 @implSpec, java9의 @index 등의 태그에 대한 내용은 추가되지 않았다. 이러한 태그들을 포함해서 주요 주석 태그들을 살펴보도록 하자!

본론

주요 주석 태그

@param

  • 매개변수가 뜻하는 명사구
  • 모든 매개변수에 설명을 달아야 한다.

@return

  • 반환 값을 설명하는 명사구
  • 반환 타입이 void가 아니라면 달아야 한다.

@throws

  • if로 시작해 해당 예외를 던지는 조건을 설명하는 절

{@code}

  • 코드 내부나 사용법 등의 언급에서 코드임을 쉽게 나타낼 수 있는 태그
  • 주석 내에 HTML 요소나 다른 자바독 태그를 무시한다.
  • 주석에 여러 줄로 된 코드 예시를 넣으려면 {@code}를 <pre>태그로 감싸준다.
  • <pre>{@code ...코드... }</pre>

{@literal}

  • 주석 내에 HTML 요소(< 등)나 다른 자바독 태그를 무시한다.
  • {@code}와 비슷하지만 코드 폰트로 렌더링하지 않는다.
  • 문서화 주석의 첫 문장은 항상 기능에 대한 요약을 기술한다. 해당 내용 중간에 .이 있는 경우 요약이 잘릴 수 있기 때문에 이 태그로 해당 단어를 안아서 설명할 수 있다.

@implSpec

  • 해당 메서드와 하위 클래스 사이의 계약을 설명한다.
  • 하위 클래스들이 그 메서드를 상속하거나 super 키워드를 이용해 호출할 때 그 메서드가 어떻게 동작하는지 명확히 인지할 수 있도록 도와준다.

{@inheritDoc}

  • 상위 타입의 문서화 주석 일부를 상속할 수 있다.

{@index}

  • 인덱스 색인을 만들 용어에 이 태그를 사용

기타 정보

package_info.java와 module_info.java

인텔리제이에서 new를 하면 package_info.java를 만날 수 있는데, 이러한 파일은 패키지 자체, 모듈 자체에 대한 문서화 주석을 위해서 존재한다.

주요 javadoc option

https://www.devkuma.com/docs/javadoc/options/ 블로그에서 너무 정리를 잘해줘서 심심하면 읽어보자..

실제 코드

ChatGPT한테 실습해볼 수 있는 코드 짜달라고 했다. 주제는 내가 계산기로 해달라고 함. 해보고 싶으면 아래 코드로 따라해 볼 수 있음.

작성 코드
폴더 구조

image

```java
//Calculator.java
package com.ssafy.calculator;

/**
 * Calculator class for basic arithmetic operations.
 *
 * @param <T> The type of numbers the calculator operates on.
 */
public class Calculator<T extends Number> {

    /**
     * Adds two numbers.
     *
     * @param a The first number.
     * @param b The second number.
     * @return The sum of the two numbers.
     * @throws IllegalArgumentException If either a or b is null.
     * @throws ArithmeticException If the sum overflows the range of the result type.
     */
    public T add(T a, T b) throws IllegalArgumentException, ArithmeticException {
        if (a == null || b == null) {
            throw new IllegalArgumentException("Input numbers must not be null");
        }

        if (a instanceof Integer) {
            int sum = a.intValue() + b.intValue();
            if ((a.intValue() > 0 && b.intValue() > 0 && sum <= 0) ||
                    (a.intValue() < 0 && b.intValue() < 0 && sum >= 0)) {
                throw new ArithmeticException("Integer overflow");
            }
            return (T) Integer.valueOf(sum);
        } else if (a instanceof Double) {
            return (T) Double.valueOf(a.doubleValue() + b.doubleValue());
        } else {
            throw new UnsupportedOperationException("Unsupported number type");
        }
    }

    /**
     * Multiplies two numbers.
     *
     * @param a The first number.
     * @param b The second number.
     * @return The product of the two numbers.
     * @throws IllegalArgumentException If either a or b is null.
     * @throws ArithmeticException If the product overflows the range of the result type.
     */
    public T multiply(T a, T b) throws IllegalArgumentException, ArithmeticException {
        if (a == null || b == null) {
            throw new IllegalArgumentException("Input numbers must not be null");
        }

        if (a instanceof Integer) {
            int product = a.intValue() * b.intValue();
            if (a.intValue() != 0 && product / a.intValue() != b.intValue()) {
                throw new ArithmeticException("Integer overflow");
            }
            return (T) Integer.valueOf(product);
        } else if (a instanceof Double) {
            return (T) Double.valueOf(a.doubleValue() * b.doubleValue());
        } else {
            throw new UnsupportedOperationException("Unsupported number type");
        }
    }
}
```

```java
//AdvancedCalculator.java
package com.ssafy.advancedcal;
import com.ssafy.calculator.Calculator;

/**
 * AdvancedCalculator class extends Calculator for additional operations.
 *
 * @param <T> The type of numbers the calculator operates on.
 * @see Calculator
 */
public class AdvancedCalculator<T extends Number> extends Calculator<T> {
    /**
     * Gets the square root of a number.
     *
     * @param number The number for which to calculate the square root.
     * @return The square root of the given number.
     * @throws IllegalArgumentException If the input number is negative.
     */
    public double calculateSquareRoot(double number) throws IllegalArgumentException {
        if (number < 0) {
            throw new IllegalArgumentException("Input number must not be negative");
        }
        return Math.sqrt(number);
    }

    /**
     * Calculates the power of a number raised to an exponent.
     *
     * @param base The base number.
     * @param exponent The exponent to which the base is raised.
     * @return The result of the base raised to the exponent.
     * @throws IllegalArgumentException If the base is negative and the exponent is not an integer.
     */
    public double power(double base, double exponent) throws IllegalArgumentException {
        if (base < 0 && exponent % 1 != 0) {
            throw new IllegalArgumentException("Negative base with non-integer exponent not supported");
        }
        return Math.pow(base, exponent);
    }

    /**
     * Calculates the inverse tangent of a number.
     *
     * @param num The number for which to calculate the inverse tangent.
     * @return The inverse tangent of the given number.
     */
    public double calculateInverseTangent(double num) {
        return Math.atan(num);
    }
}
```
</div>

명령어를 통한 javadoc 생성

javadoc -d ./docs -subpackages com.ssafy.calculator com.ssafy.advancedcal

현재 루트 디렉토리를 기준으로(인텔리제이 terminal에서 할때 꼭 src까지 한번 더 들어가서 치자.. 패키지 못찾아서 왜 안되지 한참 해맸음) docs 폴더를 만들고, 내부에 패키지에 대한 javadoc을 만들어줘!

image
오키 조아써

근데 우리는 이렇게 명령어를 입력하지 않아도 된다! 왜냐? 인텔리제이가 알아서 다 해준다!

image

image

패키지 파일을 포함하는 범위를 설정해주고(Unnamed 죄송)

image

생성된 javadoc 폴더 설정해주고 아래쪽 Generate 누르면 끝!

그러면 명령어와 동일하게 생성된 javadoc 파일을 볼 수 있다!

결론

항상 결론이 좀 싱거운데,, 사실 찾아보면서 프론트엔드와 백엔드 간의 소통방법, Spring에서의 문서화 주석에 대해서도 살펴보면서 참고하면 좋을 것 같은 글들이 몇개 있어서 한번 뽑아와봤다.

  1. [FE-BE 간의 소통을 돕는 Swagger]
  2. [Swagger: springdoc-openapi]
  3. [OpenAPI Specification을 이용한 더욱 효과적인 API 문서화]

다들 도움이 되셨나요~~

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions