코드에서 @으로 작성되는 요소를 어노테이션(Annotation)이라고 한다. 어노테이션은 클래스 또는 인터페이스를 컴파일하거나 실행할 때 어떻게 처리해야 할 것인지를 알려주는 설정 정보이다.
어노테이션은 다음 세 가지 용도로 사용된다.
@Override 어노테이션을 살펴보면 @interface로 정의되어 있다. 어노테이션을 정의하는 방법은 인터페이스를 정의하는 것과 유사하다.
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {}
속성은 타입과 이름으로 구성되며, 이름 뒤에 괄호를 붙인다.
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface PrintAnnotation {
String value() default "-";
int nubmer() default 15;
}
어노테이션 정의 시 적용 대상과 유지 기간을 정의한다.
Enum 클래스인 ElementType에 대상 종류들이 정의되어 있다.
public enum ElementType {
/** Class, interface (including annotation interface), enum, or record
* declaration */
TYPE,
/** Field declaration (includes enum constants) */
FIELD,
/** Method declaration */
METHOD,
/** Formal parameter declaration */
PARAMETER,
/** Constructor declaration */
CONSTRUCTOR,
/** Local variable declaration */
LOCAL_VARIABLE,
/** Annotation interface declaration (Formerly known as an annotation type.) */
ANNOTATION_TYPE,
/** Package declaration */
PACKAGE,
/**
* Type parameter declaration
*
* @since 1.8
*/
TYPE_PARAMETER,
/**
* Use of a type
*
* @since 1.8
*/
TYPE_USE,
/**
* Module declaration.
*
* @since 9
*/
MODULE,
/**
* Record component
*
* @jls 8.10.3 Record Members
* @jls 9.7.4 Where Annotations May Appear
*
* @since 16
*/
RECORD_COMPONENT;
}
public enum RetentionPolicy {
/**
* Annotations are to be discarded by the compiler.
*/
SOURCE,
/**
* Annotations are to be recorded in the class file by the compiler
* but need not be retained by the VM at run time. This is the default
* behavior.
*/
CLASS,
/**
* Annotations are to be recorded in the class file by the compiler and
* retained by the VM at run time, so they may be read reflectively.
*
* @see java.lang.reflect.AnnotatedElement
*/
RUNTIME
}
리플렉션을 이용해서 적용 대상으로부터 어노테이션의 정보를 얻어낼 수 있다.
import java.lang.reflect.Method;
public class Main {
public static void main(String[] args) throws Exception {
Method[] declaredMethods = Service.class.getDeclaredMethods();
for (Method method : declaredMethods) {
// PrintAnnotaion 얻기
PrintAnnotation printAnnotation = method.getAnnotation(PrintAnnotation.class);
// 설정 정보를 이용해서 선 출력
printLine(printAnnotation);
// 메소드 호출
method.invoke(new Service());
// 설정 정보를 이용해서 선 출력
printLine(printAnnotation);
}
}
private static void printLine(PrintAnnotation printAnnotation) {
if (printAnnotation != null) {
// number 속성값 얻기
int number = printAnnotation.nubmer();
for (int i = 0; i < number; i++) {
// value 속성값 얻기
String value = printAnnotation.value();
System.out.print(value);
}
System.out.println();
}
}
}