런타임시에 어노테이션 정보 사용하기
클래스에 적용된 어노테이션 정보 얻기
- 클래스.class 의 어노테이션 정보를 얻는 메소드를 이용한다.
필드, 생성자, 메소드에 적용된 어노테이션 정보 얻기
- 클래스.class의 다음 아래 표에 작성된 메소드를 이용해서
- java.lang.reflect 패키지의 Field, Constructor, Method 클래스의 배열을 얻어낸다.
리턴타입 | 메서드명 (매개변수) | 설명 |
Field[] | getFields() | 필드 정보를 Field 배열로 반환 |
Constructor[] | getConstructor() | 생성자 정보를 Constructor 배열로 반환 |
Method[] | getDeclaredMethods() | 메소드 정보를 Method 배열로 반환 |
- Field, Constructor, Method의 어노테이션 정보를 얻는 메소드를 이용
예를 들어 다음과 같은 코드가 있다.
class TestAnno {
@Annotation1
int field1;
@Annotation2
String field2;
}
TestAnno 클래스에는 field1, field2 필드가 선언되어 있고 각 필드는 Annotation이 적용되어 있다.
이럴 경우 위 표에 작성한 Field[]를 사용하여 각 필드를 배열로 저장하고, 이 배열에 저장된 내용을 가지고 각 필드에 어떤 어노테이션이 적용되었는지 알아올 수 있다. (생성자와 메서드도 동일하다.)
어노테이션 정보를 얻기 위한 메소드
리턴타입 | 메소드명 (매개변수) |
boolean | isAnnotationPresent(Class<? extends Annotation> annotationClass) |
지정한 어노테이션이 적용되었는지 여부, Class에서 호출했을 경우 상위 클래스에 적용된 경우에도 true를 리턴한다. | |
Annotation | getAnnotation(Class<T> annotationClass) |
지정한 어노테이션이 적용되어 있으면 어노테이션을 리턴하고 그렇지 않다면 null을 리턴한다. Class에서 호출했을 경우 상위 클래스에 적용된 경우에도 어노테이션을 리턴한다. | |
Annotation[] | getAnnotations() |
적용된 모든 어노테이션을 리턴한다. Class에서 호출했을 경우 상위 클래스(부모클래스)에 적용된 어노테이션도 모두 포함한다. 적용된 어노테이션이 없을 경우 길이가 0인 배열을 리턴한다. | |
Annotation[] | getDeclaredAnnotations() |
직접 적용된 모든 어노테이션을 리턴한다. Class에서 호출했을 경우 상위 클래스에 적용된 어노테이션은 포함되지 않는다. |
아래 예제를 통해 어떻게 사용하는지 직접적으로 알아보자.
순서는 다음과 같다.
1. 어노테이션 생성
2. 어노테이션이 적용된 소스 작성
3. 어노테이션이 적용된 소스를 실행할 메인 클래스 작성
1. 어노테이션 생성
/*
* 이 어노테이션은 Method에만 적용될 수 있음을 명시한다.
* 또한 실행시에도 유지되어야 하므로 Runtime 유지 정책을 명시한다.
*/
@Target()
@Retention(RetentionPolicy.RUNTIME)
public @interface PrintAnnotation {
/*
* 이름 : value
* 리턴타입 : String
* 기본값 : "-"
*/
String value() default "=";
/*
* 이름 : number
* 리턴타입 : int
* 기본값 : 15
*/
int number() default 15;
}
[PrintAnnotation.java 파일]
2. 어노테이션이 적용된 소스 작성
public class Service {
@PrintAnnotation
public void method1() {
System.out.println("실행 내용1");
}
@PrintAnnotation("*")
public void method2() {
System.out.println("실행 내용2");
}
@PrintAnnotation(value="#", number=20)
public void method3() {
System.out.println("실행 내용3");
}
}
[Service.java 파일]
3. 어노테이션이 적용된 소스를 실행할 메인 클래스 작성
import java.lang.reflect.*;
public class PrintAnnotationExample {
public static void main(String[] ar) {
// Service 클래스에 어노테이션이 적용된 메서드가 있는지 조사한다.
// 어노테이션의 element 값을 사용한다.
// 해당 메서드를 호출한다.
Method[] declaredMethods = Service.class.getDeclaredMethod();
for(Method method : declaredMethods) {
// 현재 method에 PeintAnnotation 어노테이션이 적용되어있는지 검사
if(method.isAnnotationPresent(PrintAnnotation.class)) {
// 적용되어 있을 경우 진입
PrintAnnotation printAnnotation = method.getAnnotation(PrintAnnotation.class);
// 메소드 이름 출력
System.out.println("[" + method.getName() + "]");
// 어노테이션에 만든 element에 대해 값을 가져올 때 아래와 같이 가져올 수 있다.
// System.out.println(printAnnotation.value());
// System.out.println(printAnnotation.number());
for(int i = 0; i < printAnnotation.number(); ++i) {
System.out.print(printAnnotation.value());
}
System.out.println();
// 현재 반복문에 들어와 있는 메서드 호출
try {
// 메서드가 들어있는 클래스 객체를 매개변수로 넘겨준다.
// 아래 한 줄은 마치
// Service service = new Service();
// service.method1();
// 과 같은 역할을 한다고 생각하면 된다.
method.invoke(new Service());
} catch (Exception e) {
}
System.out.pritnln();
}
}
}
}
[PrintAnnotationExample.java 파일]
실행 결과
[method1] --------------- 실행 내용1 [method2] *************** 실행 내용2 [method3] #################### 실행 내용3 |
사실 어노테이션을 직접 정의해서 사용하는 일은 그렇게 흔한 일은 아니다. (라고 알고 있다.)
하지만 직접 작성해보고 사용해보는 과정을 통해서 나중에 api에서 제공해주는 어노테이션을 만났을 때 소스 분석에 더 도움이 될거라고 생각하고 도서를 참고하여 어노테이션에 대해 정리해보았다.
나는 도움이 되었는데 누군가도 도움이 되었으면 좋겠다.
내용 참고 ] 이것이 자바다(신용권의 Java 프로그래밍 정복). 한빛미디어 출반사. 신용권 저.
'프로그래밍 언어 > Java' 카테고리의 다른 글
자바 정규표현식 비밀번호 유효성 관련 예제 (0) | 2017.06.06 |
---|---|
javaFX MDI(Multi Document Interface) 답답해서 정리 (0) | 2017.06.05 |
자바 @어노테이션 정리 1편 (0) | 2017.06.02 |
자바 함수형 인터페이스와 람다식 2편 : 생략 문법과 제약사항 (0) | 2017.05.31 |
자바 함수형 인터페이스와 람다식 1편 : 기본 개념과 사용법 (0) | 2017.05.30 |