어노테이션 어노테이션은 컴파일 과정과 실행 과정에서 코드를 어떻게 컴파일하고 처리할 것인지를 알려주는 정보이다. @가 붙는 형태로 정의된다.
어노테이션은 다음의 용도로 사용된다.
1 2 3 컴파일러에게 문법에러 체크 ex(@Override) 개발 툴이 코드를 자동 생성할 수 있도록 정보제공 실행시 특정기능을 실행하도록 정보제공
어노테이션 정의 및 사용법 어노테이션 정의는 다음과 같이 할 수 있다.
Annotation 1 2 3 4 public @interface SHAnnotation { String feature () ; int age () default 0 ; }
위에 정의한 어노테이션을 사용하기 위해서는 다음과 같이 사용할 수 있다.
Annotation 1 2 3 4 @SHAnnotation(feature="개발자", age=27) ;혹은 @SHAnnotation(feature="개발자") ;
어노테이션을 적용할 수 있는 대상은 java.lang.annotation.ElementType에 정의 되어있다. 해당 열거형을 보면 아래와 같이 다양하게 존재한다. 즉 어노테이션을 적용할 수 있는 대상은 다음과 같다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 // Field descriptor #37 Ljava/lang/annotation/ElementType; public static final enum java.lang.annotation.ElementType TYPE; // Field descriptor #37 Ljava/lang/annotation/ElementType; public static final enum java.lang.annotation.ElementType FIELD; // Field descriptor #37 Ljava/lang/annotation/ElementType; public static final enum java.lang.annotation.ElementType METHOD; // Field descriptor #37 Ljava/lang/annotation/ElementType; public static final enum java.lang.annotation.ElementType PARAMETER; // Field descriptor #37 Ljava/lang/annotation/ElementType; public static final enum java.lang.annotation.ElementType CONSTRUCTOR; // Field descriptor #37 Ljava/lang/annotation/ElementType; public static final enum java.lang.annotation.ElementType LOCAL_VARIABLE; // Field descriptor #37 Ljava/lang/annotation/ElementType; public static final enum java.lang.annotation.ElementType ANNOTATION_TYPE; // Field descriptor #37 Ljava/lang/annotation/ElementType; public static final enum java.lang.annotation.ElementType PACKAGE; // Field descriptor #37 Ljava/lang/annotation/ElementType; public static final enum java.lang.annotation.ElementType TYPE_PARAMETER; // Field descriptor #37 Ljava/lang/annotation/ElementType; public static final enum java.lang.annotation.ElementType TYPE_USE;
어노테이션이 적용될 대상을 지정할 땐 @Target를 활용한다.
Annotation 1 2 3 4 5 6 7 8 9 10 import java.lang.annotation.Target;import java.lang.annotation.ElementType;@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD}) public @interface SHAnnotation { String feature () ; int age () default 0 ; }
그럼 아래와 같이 어노테이션 적용이 가능해진다.
Annotation 1 2 3 4 5 6 7 8 9 10 11 12 13 @SHAnnotation(feature="개발자", age=27) public class AnnotationTest { @SHAnnotation(feature="디자이너") public void method1 () { System.out.println("메소드1" ); } @SHAnnotation(feature="기획자", age=30) public void method2 () { System.out.println("메소드2" ); } }
어노테이션 유지 정책 어노테이션은 용도에 따라 어느 범위까지 유지할 것인지 지정 가능하다. 세가지로 나뉘는데 다음과 같다.
1 2 3 SOURCE - 소스상에서만 유지 CLASS - 바이트 코드 까지 유지 RUNTIME - 바이트 코드까지 유지하며 리플렉션을 이용해 런타임 시 어노테이션 정보를 얻을 수 있다.
리플렉션? 위에 리플렉션에 대해 설명하자면 런타임 시에 클래스의 메타 정보를 얻는 기능을 의미한다. 클래스의 필드, 생성자, 메소드, 적용된 어노테이션 등을 런타임 시에 알아낼 수 있다.
다시 돌아와서 어노테이션의 유지는 @Retention으로 지정할 수 있다. 대부분 어노테이션은 런타임시에 유지되도록 하는경우가 많다. 다음은 어노테이션이 런타임시에 유지되도록 하는 코드이다.
Annotation 1 2 3 4 5 6 7 8 9 10 11 12 import java.lang.annotation.Target;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface SHAnnotation { String feature () ; int age () default 0 ; }
런타임 중 어노테이션 정보 사용 어노테이션을 만들었으면 사용방법 또한 알아야 할 것이다. 이에 대해 자세히 알아보자 클래스에 적용된 어노테이션 정보를 얻으려면 Class 클래스를 이용하면 되지만 필드, 생성자, 메소드에 적용된 어노테이션 정보를 얻으려면 Class 클래스의 메소드를 통해 리플렉션 과정이 필요하다. 이 말이 이해가 안되면 코드를 보고 이해하자.
위 까지 모든 과정을 거쳤으면 아래 실습이 문제없을것이다.
Annotation 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 import java.lang.reflect.Method;public class PrintAnnotation { public static void main (String[] args) { SHAnnotation shAnnotation; shAnnotation = AnnotationTest.class.getAnnotation(SHAnnotation.class); System.out.println(AnnotationTest.class.getName()); System.out.println(shAnnotation.feature()); System.out.println(); Method[] declaredMethods = AnnotationTest.class.getDeclaredMethods(); for (Method method:declaredMethods) { shAnnotation = method.getAnnotation(SHAnnotation.class); if (method.isAnnotationPresent(SHAnnotation.class)) { System.out.println(method.getName()); System.out.println(shAnnotation.feature()); } try { method.invoke(new AnnotationTest ()); System.out.println(); }catch (Exception e) { System.out.println(e.getStackTrace()); } } } }