[Kotlin] Annotation Targets
2019-06-12 에 작성한 글을 옮겨왔습니다.
@Doc 어노테이션을 붙였을 때 문서화가 안되는 에러가 발생하였습니다.
디컴파일된 자바코드를 확인해보기 전까지는 다른 건 Java로 짰는데 이 클래스는 코틀린이라서 그런가? 라는 말도 안되는 의심을 했습니다..!:joy:
코틀린은...
코틀린의 property는 자바의 필드, getter, setter, 그리고 접근자의 파라미터로 해석될 수 있습니다.
그리고 코틀린의 property가 primary constructor에 선언 된 경우에는 생성자의 파라미터로도 해석이 됩니다.
의도하지 않은 방향으로 코드가 생성 될 수도 있으므로, annotation의 use-site 같이 명확한 용도를 정의해줘야 합니다.
Annotation Use-site Targets
annotation의 용도를 선언하기 위해 사용합니다.
use-site 목록
- property (Java annotation은 해당 값 사용할 수 없음)
- field
- get (getter)
- set (setter)
- receiver
- param (생성자 파라미터)
- setparam
- delegate
- file
사용방법
use-site target
을 명시하지 않으면 사용한 annotation의 @Target 이 사용됩니다.
ex)
@Target({ElementType.PARAMETER, ElementType.FIELD, ElementType.METHOD})
만약 다수의 @Target이 존재한다면, 적용 가능한 use-site부터 순서대로 적용됩니다.
- param
- property
- field
문제해결
DocGenerator.java 는 필드
를 기준으로 하여 @Doc 어노테이션이 붙은 필드를 가져와서 문서화 합니다.
...
for (Field field : fieldList) {
Doc doc = field.getAnnotation(Doc.class);
if (doc != null) {
...
수정 전
오류가 났을 경우의 data class는 일반 자바 클래스에서 어노테이션을 사용하는 것과 같이 작성하였습니다.
data class ReceiverResponse(@Doc(desc = "수령자 수", example = "")
val receiverCount: Long,
@Doc(desc = "수령자 정보", example = "", child = true)
val receivers: List<Receiver>)
이 경우의 자바바코드를 확인하면
위에서 명시한 것과 같이, 다수의 @Target 이 존재하는 경우에는 param
, property, field 순으로 적용되므로 변환된 자바코드의 생성자 파라미터에 어노테이션이 붙어있는 것을 확인할 수 있습니다.
field.getAnnotations(Doc.class)
의 부분에서 null이 반환 되었고, 문서화 테스트케이스는 당연히 에러가 발생하였습니다.
수정 후
use-site target을 사용하여 다음과 같이 변경하여 주면 정상 동작하는 것을 확인할 수 있습니다.
data class ReceiverResponse(@field:Doc(desc = "수령자 수", example = "")
val receiverCount: Long,
@field:Doc(desc = "수령자 정보", example = "", child = true)
val receivers: List<Receiver>)
수정 한 후의 자바코드:
각 필드에 원래의 의도대로 @Doc 어노테이션이 붙어있는 것을 확인 할 수 있습니다!
에러도 해결!
교훈: 코틀린을 제대로 알고 사용하자
출처