나의 지식 보관소
어노테이션 본문
어노테이션은 컴파일러에게 코드 문법 에러를 체크하고, 소프트웨어 개발 툴이 빌드나 배치 시 코드를 자동으로 생성하고, 런타임 시 특정 기능을 실행하도록 정보를 제공한다.
어노테이션 타입을 정의하는 것은 인터페이스를 정의하는 것과 유사하다. 어노테이션 타입을 정의하기 위해서는 다음과 같이 @interface를 사용하여 정의하고, 다음과 같이 사용한다.
public @interface AnnotationName{
//어노테이션 정의
}
@AnnotationName //어노테이션 사용
모든 어노테이션은 멤버로 엘리먼트를 가지며, 엘리먼트는 타입과 이름으로 구성되고, 디폴트 값을 가질 수 있다.
엘리먼트의 타입은 int나 double 같은 기본적인 데이터 타입과 열거 타입, Class타입, 그리고 배열도 올 수 있다.
public @interface AnnotationTest {
String StringElement();
int intElement() default 3;
}
위의 코드의 AnnotationTest는 String형 엘리먼트와 int형 엘리먼트를 가지고, int형 엘리먼트는 디폴트 값으로 3을 가진다. 이렇게 정의된 어노테이션을 사용할 때에는 아래와 같이 사용한다.
@AnnotationTest(StringElement = "Hello")
//또는
@AnnotationTest(StringElement = "Hello", intElement = 5)
AnnotationTest를 사용할 때 intElement는 디폴트 값을 가지기 때문에 생략할 수 있다.
어노테이션 적용 대상
어노테이션을 적용할 수 있는 대상은 아래와 같이 java.lang.annotation.ElementType 열거 상수로 정의 되어있다.
ElementType 열거 상수 | 적용 대상 |
TYPE | 클래스, 인터페이스, 열거 타입 |
ANNOTATION_TYPE | 어노테이션 |
FIELD | 필드 |
CONSTRUCTOR | 생성자 |
METHOD | 메서드 |
LOCAL_VARIABLE | 로컬변수 |
PACKAGE | 패키지 |
어노테이션이 적용될 수 있는 대상을 지정할 때는 @Target 어노테이션을 사용한다. 또한 @Target는 어노테이션이 적용될 대상을 복수개로 지정하기 위해서 엘리먼트인 value가 ElementType배열을 값으로 가진다.
아래와 같이 적용할 대상을 지정할 수 있다.
@Target({ElementType.TYPE, ElementType.CONSTRUCTOR})
public @interface AnnotationTest {
String StringElement();
int intElement() default 3;
}
어노테이션 유지 정책
어노테이션 정의 시 사용 용도에 따라 해당 어노테이션을 어느 범위까지 유지할지 지정해야 한다. 쉽게 말해 소스상에 유지할건지, 컴파일된 클래스까지 유지할건지, 런타임시에도 유지할것인지를 지정해야한다. 어노테이션 유지 정책은 java.lang.annotation.RetentionPolicy 열거 상수로 아래와 같이 정의돼있다.
RetentionPolicy 열거 상수 | 설명 |
SOURCE | 소스상에서만 어노테이션 정보를 유지한다. 소스 코드를 분석할 때만 의미가 있으며, 바이트 코드 파일에는 정보가 남지 않는다. |
CLASS | 바이트 코드 파일까지 어노테이션 정보를 유지한다. 하지만 리플렉션을 이용해서 어노테이션 정보를 얻을 수는 없다. |
RUNTIME | 바이트 코드 파일까지 어노테이션을 유지하면서 리플렉션을 이용해서 런타임 시에 어노테이션 정보를 얻을 수 있다. |
어노테이션 유지 정책을 지정할 때에는 @Retention 어노테이션을 사용해서 위 세 가지 상수중 하나를 선택하면 된다.
아래와 같이 어노테이션 유지 정책을 지정할 수 있다.
@Target({ElementType.TYPE, ElementType.CONSTRUCTOR})
@Retention(RetentionPolicy.RUNTIME)
public @interface AnnotationTest {
String StringElement();
int intElement() default 3;
}