annotation은 주석이라는 뜻이다. 주석은 어떤 대상에 대한 추가적인 정보를 제공하기 위해 주로 사용한다. Java에서는 프로그램의 일부에 대한 추가적인 정보를 제공하는 것이 annotation이다. 자바는 //
와 /** **/
기호를 통한 주석말고 @
기호를 이용한 독자적인 annotation 시스템을 구축하고 있다.
optional한 meta data를 제공하는 것이 annotation의 사용 목적이라고 할 수 있는데, 사실 주석이라는 의미에 맞게 annotation이 프로그램에게 미치는 직접적인 영향은 전혀 없다. 다만, 프로그래머와 compiler, 그리고 IDE에게 annotation을 통해 힌트를 주는 역할을 할 수 있다.
예를 들어 유명한 annotation인 @Override
를 메소드에 붙였을때, 해당 메소드의 스펠링이 틀리면 IDE는 문제를 캐치해서 다음과 같은 메시지를 프로그래머에게 제공해줄 수 있다.
Method does not override method from its superclass.
그런데 현대 자바의 수많은 활용에는 optional meta data를 제공해주는 것 외에도 프로그램에 직접적인 영향을 미치도록 구현한 활용 사례가 많다. 예를 들어 @Test
, @Autowired
는 한정된 맥락에서 프로그램에 직접적인 영향을 미친다.
Annotation 인터페이스는 다른 인터페이스들과 달리 다음과 같은 특별한 특징이 있다.
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Nickname {
String[] value() default {};
}
@interface
,@target
,@retention
을 사용해서 custom annotation을 정의할 수 있다.
@target은 커스텀 어노테이션을 코드상의 합법적인? 위치를 정해주는 annotation이다. ElementType
enum과 함께 사용되며, 해당 enum은 다음과 같은 enum 상수를 가진다. 하나 이상의 enum을 사용할 수 있다.
ElementType의 상수들
TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE,
ANNOTATION_TYPE, PACKAGE, TYPE_PARAMETER, TYPE_USE
@Target({ElementType.METHOD, ElementType.FIELD})
@retention은 자바컴파일러와 런타임 환경에서 custom annotation에 대한 처리방식을 명시해주는 annotation이다. 다음 enum 상수중 하나를 사용할 수 있다.
RetentionPolicy enum의 상수들
SOURCE,CLASS,RUNTIME
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
CLASS
클래스 파일에는 표시되지만 런타임일때는 사라지도록. 거의 쓰이지 않지만, JVM bytecode 분석툴 등에 가끔 활용된다.
RUNTIME
JVM 실행 중에도 유저 코드 접근이 가능하도록. reflection을 통해 해당 기술이 가능해진다.
@Documented
와 함께 쓰인 코드 요소는 javadocs
같은 공식문서의 일부가 된다. 그래서 @Documented
을 붙인 후 자바독을 생성하면 default로 해당 자바독에 요소가 보인다. 문서화에 주로 사용된다.
컴파일 단계에서 소스 코드를 검사, 조작할 수 있게 해주는 자바의 기능이다.
자바 내부적으로 annotation 처리를 여러 round에 걸쳐서 하게 된다. 각 단계마다 컴파일러가 annotation을 찾아서 그에맞는 annotation processor를 찾아주도록 한다. processing round는 이전 단계의 output을 input으로 받는데, input이 존재하지 않을 때까지 반복된다.
javax.annotation.processing
패키지에 annotation processing과 관련된 다양한 파일들이 있다. 편리하게 어노테이션 프로세서를 구현할 수 있는 AbstractProcessor
를 상속받아 사용한다. options, annotation types, and source version등을 체크할 수 있다. custom annotation processor는 포스팅 하나를 따로 파야될 분량이라 다음 포스팅에서 정리할 것이다.
참고
Java in a Nutsell, 7th Edition
https://docs.oracle.com/en/java/javase/15/docs/api/java.base/java/lang/annotation/Annotation.html
https://docs.oracle.com/en/java/javase/15/docs/api/java.base/java/lang/annotation/Documented.html
https://docs.oracle.com/en/java/javase/15/docs/api/java.compiler/javax/annotation/processing/Processor.html
https://www.baeldung.com/java-custom-annotation
https://www.baeldung.com/java-annotation-processing-builder
계속해서 문서를 업데이트하고 있습니다. 언제든지 댓글피드백 남겨주세요. 😉