어노테이션은 메타 데이터로 볼 수 있습니다. 애플리케이션이 처리해야 하는 데이터가 아니라 컴파일 과정에서 코드를 어떻게 컴파일 하고 처리해야 하는지 알려주는 것이 메타데이터 입니다.
컴파일러에게 코드 문법 에러를 체크하도록 정보를 제공합니다
소프트웨어 개발 툴이 빌드나 배치 시 코드를 자동으로 생성할 수 있도록 정보를 제공합니다
실행시 특정 기능을 실행하도록 정보를 제공합니다
컴파일러에게 작성된 코드의 문법상 에러를 체크하도록 정보를 제공하는 목적으로 대표적으로 @Override 어노테이션이 있습니다. @Override는 메소드를 선언해 놓으면 사용시 메서드가 오버라이드 (재정이) 된 것을 컴파일러에게 알려줘서 컴파일러는 오버라이드를 검사하도록 합니다.
정확히 오버라이드가 되지 않았다면 컴파일러는 에러가 발생하기도 합니다. 어노테이션은 빌드 시 자동으로 XML 설정 파일을 생성하거나 배포를 위해 JAR 압축 파일을 생성하는데에도 사용됩니다. 그래서 실행시 클래스 역할을 정의하기도 합니다.
어노테이션 정의 방법은 인터페이스 정의와 유사합니다. @interface를 사용하여 어노테이션 정의를 합니다.
public @interface AnnotationClass { }
이렇게 정의한 어노테이션 코드는 아래와 같이 사용합니다
@AnnotationClass
어노테이션은 element를 멤버로 가질 수 있습니다. 엘리먼트들은 타입과 이름으로 구성되어지며 디폴트 값을 가질 수 있습니다.
public @interface AnnotationClass { 타입 elementName() [default 값]; }
엘리먼트의 타입은 int, double 같은 기본 데이터 타입과 문자열, 열거, Class, 배열 타입이 사용 가능합니다. 엘리먼트의 이름 뒤에는 () 괄호를 붙여야 합니다. 사용 방법은 아래와 같습니다.
public @interface AnnotationClass {
String elementName();
int elementCnt() default 5;
}
정의한 어노테이션을 코드에 적용해보면 아래와 같이 사용할 수 있습니다.
@AnnotationClass(elementName = "test", elementCnt = 1)
@AnnotationClass(elementName = "test")
Element Type 열거 상수 | 적용 대상 |
TYPE | 클래스, 인터페이스, 열거타입 |
ANNOTATION_TYPE | 어노테이션 |
FIELD | 필드 |
CONSTRUCTOR | 생성자 |
METHOD | 메서드 |
LOCAL_VARIABLES | 로컬 변수 |
PACKAGE | 패키지 |
어노테이션 적용 대상의 지정은 @Target 어노테이션을 사용합니다. @Target의 기본 엘리먼트인 value ElementType 배열은 값을 가집니다. 이것은 어노테이션이 적용될 대상을 복수개로 지정하기 위해서입니다.
그리고 아래와 같이 어노테이션 적용 대상을 지정하고 실제 사용하는 모습을 확인할 수 있습니다.
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
public @interface AnnotationClass { }
@AnnotationClass
public class ClassName {
@AnnotationClass
private String fieldName;
@AnnotationCalss
public void methodName() { }
}
어노테이션 정의 시 한 가지 더 축하랄 것은 사용 용도에 따라 @AnnotationClass를 어느 범위까지 유지할 것인지 지정하는 것입니다. 소스나 컴파일된 클래스까지인지, 런타임 시에도 유지할 것인지 지정할 수 있습니다.
유지정책은 java.lang.annotation.RetentionPolicy 열거 상수로 정의되어 있습니다.
SOURCE : 소스상에서만 어노테이션 정보를 유지하며 소스 코드를 분석할 때만 의미가 있습니다. 바이트 코드 파일에는 정보가 남지 않습니다.
CLASS : 바이트 코드 파일까지 어노테이션 정보를 유지합니다. 하지만 리플렉션을 이용해서 어노테이션 정보를 얻을 수 없습니다.
RUNTIME : 바이트 코드 파일까지 어노테이션 정보를 유지하려면 리플렉션을 이용해 런타임 시 어노테이션 정보를 얻을 수 있습니다
런타임 시점에 클래스의 메타 정보를 얻는 기능입니다. 만약 클래스가 갖고 있는 필드는 무엇이 있는지, 어떤 생성자를 갖고 있는지, 어떤 메서드를 갖고 있는지, 적용된 어노테이션이 무엇인지 알아내는 목적으로 사용됩니다.
런타임 시점의 어노테이션 정보를 얻으려면 유지정책은 RUNTIME으로 설정해야 합니다
어노테이션 유지정책을 지정할 때 @Retention 어노테이션을 사용합니다. @Retention 기본 엘리먼트인 value는 RententionPolicy 타입으로 세 가지 상수 중 하나를 지정하면 됩니다.
@Target({ElementType.Type, ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface AnnotationClass { }
어노테이션 자체는 아무런 동작을 갖지 않으며 단지 표시일 뿐입니다. 리플랙션을 이용하여 어노테이션 적용 여부와 엘리먼트 값을 읽고 적절하게 처리가 가능합니다. 클래스에 적용된 어노테이션 정보는 java.lang.Class를 이용하면 됩니다. 필드, 생성자, 메서드에 적용된 어노테이션 정보는 Class의 다음 메소드를 통해 java.lang.reflect 패키지의 Field, Constructor, Method 타입의 배열을 얻어야 합니다.
리턴 타입 | 메서드명 (매개변수) | 설명 |
Field[] | getFields() | 필드 정보를 Field 배열로 리턴 |
Constructor[] | getConstructors() | 생성자 정보를 Constructor 배열로 리턴 |
Method[] | getDeclaredMethods() | 메소드 정보를 Method 배열로 리턴 |
아래는 적용된 어노테이션 정보를 얻을 있습니다.
리턴타입 | 메서드명 |
boolean | isAnnotationPresent(Class<? extentds Annotation> annotationClass 지정한 어노테이션이 적용되었는지 여부, Class에서 호출시 상위 클래스에 적용된 경우 true를 반환합니다 |
Annotation | getAnnotation(Class<T> annotationClass) 지정한 어노테이션이 적용되어 있으면 어노테이션을 리턴하고 그렇지 않으면 null을 리턴합니다. |
Annotation[] | getAnnotation() 적용된 모든 어노테이션을 리턴합니다. Class 에서 호출시 상위 클래스에 적용된 클래스도 모두 리턴합니다. 적용된 어노테이션이 없을시 길이가 0인 배열을 리턴합니다 |
Annotation[] | getDeclaredAnnotations() 직접 적용된 모든 어노테이션을 리턴합니다. 상위 클래스에 적용된 어노테이션은 포함되지 않습니다 |
엔티티 매핑 (@Table, Sequence) (0) | 2024.01.11 |
---|---|
클래스 상속 (생성자 호출) 자바 (1) | 2024.01.10 |
열거 타입 정리 (JAVA) (1) | 2024.01.08 |
JVM 튜닝 방법 (Jrokit) (1) | 2024.01.07 |
가비지 컬렉터 (Serial GC, Parallel GC) (1) | 2024.01.06 |
댓글 영역