-
Notifications
You must be signed in to change notification settings - Fork 0
Description
서론
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한테 실습해볼 수 있는 코드 짜달라고 했다. 주제는 내가 계산기로 해달라고 함. 해보고 싶으면 아래 코드로 따라해 볼 수 있음.
작성 코드
폴더 구조
```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을 만들어줘!
근데 우리는 이렇게 명령어를 입력하지 않아도 된다! 왜냐? 인텔리제이가 알아서 다 해준다!
패키지 파일을 포함하는 범위를 설정해주고(Unnamed 죄송)
생성된 javadoc 폴더 설정해주고 아래쪽 Generate 누르면 끝!
그러면 명령어와 동일하게 생성된 javadoc 파일을 볼 수 있다!
결론
항상 결론이 좀 싱거운데,, 사실 찾아보면서 프론트엔드와 백엔드 간의 소통방법, Spring에서의 문서화 주석에 대해서도 살펴보면서 참고하면 좋을 것 같은 글들이 몇개 있어서 한번 뽑아와봤다.
- [FE-BE 간의 소통을 돕는 Swagger]
- [Swagger: springdoc-openapi]
- [OpenAPI Specification을 이용한 더욱 효과적인 API 문서화]
다들 도움이 되셨나요~~




