annotation 내부를 들여다보면 @Retention을 볼 수 있는데 개념을 어렴풋이 알고만 있다가 한 번 정리하고자 글을 쓴다.
Indicates how long annotations with the annotated type are to be retained. If no Retention annotation is present on an annotation type declaration, the retention policy defaults to RetentionPolicy.CLASS.
A Retention meta-annotation has effect only if the meta-annotated type is used directly for annotation. It has no effect if the meta-annotated type is used as a member type in another annotation type.
Retention에 대한 java docs 내용을 가져와봤다.
말 그대로 annotation을 언제까지 유지할 것인지에 대한 meta annotation이다. 선언하지 않으면 기본 값으로 'CLASS'에 해당하는 값을 가진다. 다른 annotation에서 멤버 타입으로 사용되는 메타 annotation에는 효과가 없다고 한다.
(meta annotation: 다른 annotaion에서 사용될 수 있는 annotation)
Retention Policy: Enum 타입으로 3가지 상수를 가지고 있다.
- CLASS: annotatation이 class 파일까지 저장되나 런타임 시까지 가져가지 않는다.
- RUNTIME: 런타임 시까지 annotation을 가져가며 java Reflect API를 통해 정보를 제공한다.
- SOURCE: annotation은 컴파일러에 의해 버려진다.
이렇게 정의만 알면 살짝 이해하기 어렵다.
많이 사용하는 annotation 예시와 함께 보자.
CLASS
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE, ElementType.TYPE_USE})
@Retention(RetentionPolicy.CLASS)
@Documented
public @interface NonNull {
}
lombok library에 있는 @NonNull에서 사용되고 있다.
개인적으로 좀 애매한 정책이라고 생각했다.
대부분의 lombok annotation은 SOURCE 정책을 가져가는 한편, 왜 @NonNull은 CLASS 정책을 가져갈까.
너무 깊이 빠질 필요는 없지만 비슷한 고민을 한 분이 있어 공유해본다.
https://stackoverflow.com/questions/68080679/why-does-lomboks-nonnull-have-class-retention
결론적으로, byte code에 주석을 달아 다른 Nonnull annotation과 차별을 둔다던지 그런 용도로 사용할수도 있고 컴파일 시 다른 용도로 사용하는 것으로 추측된다.
그 외에도 클래스로딩 시 무언가를 하고 싶은 경우에도 사용할 수 있다고 한다.
RUNTIME
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
...
}
런타임 시에도 필요한 annotation의 한 예이다. spring을 띄웠을 때 bean을 주입하기 위해서 사용할 수 있고, 여기서는 controller의 역할을 하기 위한 다른 작업이 필요해서 RUNTIME 정책을 쓴걸로 추측된다. 많은 annotation이 이 정책을 사용한다.
SOURCE
import java.lang.annotation.*;
...
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
java에서 제공하는 annotation 중 하나로 interface를 구현하거나 상속받는 클래스에 대해 구현을 강제한다. 이렇게 byte code에 남아있을 필요도 없고 런타임 시에 활용될 필요가 없을 때 사용된다.
https://www.intertech.com/spring-4-meta-annotations/
https://docs.oracle.com/javase/8/docs/api/java/lang/annotation/RetentionPolicy.html
https://jeong-pro.tistory.com/234#recentComments
https://sas-study.tistory.com/329(https://sas-study.tistory.com/329
'Backend > Java' 카테고리의 다른 글
final (0) | 2022.08.16 |
---|---|
Annotation(@) (0) | 2022.08.15 |
순수 함수란? (0) | 2022.08.12 |
람다식(Lambda Expression), 람다란(Lambda)? (0) | 2022.08.12 |
Reflection(리플렉션) (0) | 2022.08.08 |