annotation
은 인터페이스의 특별한 형태이다.
annotation
은 인터페이스와 비교하여 아래와 같은 특징을 가진다.
java.lang.annotation.Annotation
을 묵시적으로 상속한다.generic
을 지원하지 않는다.exception
을 throw
하는 메소드를 정의할 수 없다.어노테이션을 정의하기 전에 meta-annotation
이라는 것을 알아야 한다.
meta-annotation
은 java.lang.annotation
에 정의되어 있으며 개발자가 정의할 새로운 어노테이션의 사용 규칙을 지정할 수 있게 하며 컴파일러와 런타임이 개발자가 정의한 어노테이션을 인식할 수 있게 한다.
두 가지의 primary meta-annotation
이 존재한다. 각각 @Target
, @Retention
이며 둘 다 커스텀 어노테이션을 정의할 때 반드시 요구된다.
@Target
은 어노테이션이 자바 코드에서 어디에 위치해야 하는지를 나타낸다.
ElementType
이라는 enum으로 값을 지정할 수 있으며 하나 이상의 위치를 지정할 수 있다.
Values | Location |
---|---|
TYPE | class, interface (including annotation type), enum |
FIELD | class member variable (includes enum constants) |
METHOD | method |
PARAMETER | paramter |
CONSTRUCTOR | constructor |
LOCAL_VARIABLE | local_variable |
ANNOTATION_TYPE | annotation_type |
PACKAGE | package |
TYPE_PARAMETER | type_parameter (since 1.8) |
TYPE_USE | type_use (since 1.8) |
module | module (since 9) |
javac
와 자바 런타임이 커스텀 어노테이션을 처리해야 하는 시점을 나타낸다.
Values | Location |
---|---|
SOURCE | javac 컴파일 시점에 삭제된다. |
CLASS | .class 에서도 (컴파일 이후에도) 살아있지만 반드시 JVM 런타임 시점에 접근될 필요는 없다. 아주 가끔 사용되며 JVM 바이트 코드를 오프라인 환경에서 분석할 때 유용하게 사용할 수 있다. |
RUNTIME | 런타임 시점에 적용될 수 있다는 것을 의미한다. reflection에 의해 사용될 수 있다. |
어노테이션이 자동으로 상속될 수 있다는 것을 나타낸다.
그러니까 A 클래스에 @Inherited
, @Getter
를 가지고 있을 때 자식 클래스 또한 @Getter
를 가지고 있다는 뜻이다.
javadoc 또는 그와 유사한 툴에 의해서 문서화할 수 있다는 것을 나타낸다.
이 어노테이션을 사용하여 커스텀 어노테이션을 정의한다면 javaDoc으로 볼 수가 있다는 뜻이다.
다음과 같은 코드를 작성해보자
@Documented
public @interface MyFirstDocumentedAnnotation {
}
그 후 터미널에서 javadoc {MyFirstDocumentedAnnotation의 경로}
를 입력하면 해당 프로젝트 루트경로에 파일이 여러개 생성된다. 그 중 index.html
을 클릭하면 다음과 같은 화면이 뜨게 된다.
오라클에서만 보던 것을 내가 직접 만들다니 신기하다
intelliJ에서도 Tools -> Generate javadoc
을 클릭하면 여러가지 속성을 쉽게 조정하여 javadoc을 생성할 수 있다.
어노테이션을 처리해주는 녀석이다.
대표적으로 롬복이 어노테이션 프로세서라고 한다.
컴파일 시점에 코드가 추가된다. 롬복의 @Setter
로 예시를 들면 컴파일 후 .class
파일에는 void setA(String a)
메소드가 생성되어 있다.