- 어노테이션 용도
- 컴파일러에게 코드 작성 문법 에러를 체크하도록 정보 제공 (메서드 재정의 여부 확인 - @Override)
- 개발 툴에서 빌드나 배치 시 코드 자동 생성할 수 있게 정보 제공 (XML 설정 파일 자동 생성하거나 배포를 위한 JAR 압축파일 자동 생성 등)
- 실행 시(런타임 시) 특정 기능 실행하도록 정보 제공 (객체가 애플리케이션 내부에서 할 역할을 정의 가능 (서블릿, 컨트롤러...)
- 어노테이션 엘리먼트 멤버
public @interface AnnotationName {
타입 elementName() [default 값];
...
}
엘리먼트 "타입"은 기본 타입과 참조 타입 모두 사용 가능.
<!-- 타입 작성 예시 -->
public @interface PrintAnnotation {
String elementName1();
int elementName2() default 5;
}
- 기본 엘리먼트 : value
어노테이션 적용 코드에서 값만 주면 value() 값으로 들어간다.
[1] @AnnotationName("값") <===== 값만 주면!
public @interface AnnotationName {
[2] String value(); <================= 기본 엘리먼트의 값으로 들어감
int elementName() default 5;
}
- 원칙은 @AnnotationName(value="값") 으로 쓰나 value= 는 생략 가능
- 단! 두 개 이상의 속성을 쓸때는 엘리먼트 명과 값으로 작성해야 함.
- 작성 예시 : @AnnotationName(value="값", elementName=3)
- 어노테이션 적용 대상
ElementType 열거 상수 | 적용 대상 |
TYPE | 클래스, 인터페이스, 열거 타입 |
ANNOTATION_TYPE | 어노테이션 |
FIELD | 필드 |
CONSTRUCTOR | 생성자 |
METHOD | 메서드 |
LOCAL_VARIABLE | 로컬 변수 |
PACKAGE | 패키지 |
- 실습
1. 이클립스에서 ctrl + n 혹은 생성 아이콘을 눌러서 Annotation을 생성해주고 엘리먼트를 선언한다.
public @interface PrintAnnotation {
String value() default "-";
int number() default 15;
}
코드는 "-" 하이픈을 15개 출력하겠다는 것 ( --------------- )
작성했다면 최상단에 다음과 같이 작성한다.
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface PrintAnnotation {
String value() default "-";
int number() default 15;
}
@Target 부분을 보면 마지막에 .METHOD가 붙었는데 이는 메서드에만 적용 할수 있다는 뜻.
즉, PrintAnnotation 은 메서드에만 적용할 수있다는 뜻.
@Retention 부분은 어노테이션의 유지 정책으로 언제까지 어노테이션 정보가 유지될 거냐라는 것을 뜻한다.
2. Service 클래스를 생성한다.
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");
}
}
3. 실행 클래스를 만든다. (PrintAnnotaionExample 클래스를 만들어준다.)
public class PrintAnnotationExample {
public static void main(String[] args) {
Method[] declaredMethods = Service.class.getDeclaredMethods();
}
Method [] 부분에 빨간 줄이 뜨면 import가 안된 것이기 때문에 ctrl + shift + o를 눌러서 import 해준다.
public class PrintAnnotationExample {
public static void main(String[] args) {
Method[] declaredMethods = Service.class.getDeclaredMethods();
for(Method method : declaredMethods) {
if(method.isAnnotationPresent(PrintAnnotation.class)) {
PrintAnnotation printAnnotation = method.getAnnotation(PrintAnnotation.class);
// 메소드 이름 출력
System.out.println("[" + method.getName() + "]");
// 구분선 출력
for(int i=0; i<printAnnotation.number(); i++) {
System.out.print(printAnnotation.value());
}
System.out.println();
// 메소드 호출
method.invoke(new Service());
}
}
}
}
## for문 안에 있는 System.out.print의 print"ln"이 아니라 print이니 잘 작성하자.
method.invoke(new Service()) 코드를 해석해보면
>> Service 객체가 가지고 있는 method 이름을 호출한다 << 로 보면 된다.
!! method.invoke(new Service()) 코드를 쓰면 빨간 줄이 뜨는데 이유는 예외처리를 해줘야 하기 때문이다.
해당 코드에 커서를 올리고 ctrl + 1 눌러서 surround with try/catch를 만들자
그리고 아래 코드처럼 수정하자. (예외 처리는 예외처리 공부할 때 하기 때문에 간단하게 수정함)
=================== 이랬던 코드를 ======================
try {
method.invoke(new Service());
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
=================== 이렇게 수정 ======================
try {
method.invoke(new Service());
} catch (Exception e) {
}
- 최종 코드
package chap06.sec15.exam01_annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class PrintAnnotationExample {
public static void main(String[] args) {
Method[] declaredMethods = Service.class.getDeclaredMethods();
for(Method method : declaredMethods) {
if(method.isAnnotationPresent(PrintAnnotation.class)) {
PrintAnnotation printAnnotation = method.getAnnotation(PrintAnnotation.class);
// 메소드 이름 출력
System.out.println("[" + method.getName() + "]");
// 구분선 출력
for(int i=0; i<printAnnotation.number(); i++) {
System.out.print(printAnnotation.value());
}
System.out.println();
// 메소드 호출
try {
method.invoke(new Service());
} catch (Exception e) {
}
System.out.println();
}
}
}
}
블록과 블럭 사이에 있는 System.out.println() 이 코드는 줄 내림을 위한 것임.
실행해보자. (ctrl + F11)
'study > JAVA' 카테고리의 다른 글
부모 생성자 호출(super(...)) (0) | 2022.02.24 |
---|---|
상속(Inheritance) - 클래스 상속 (0) | 2022.02.24 |
Getter와 Setter (0) | 2022.02.18 |
접근 제한자( Access Modifier) (0) | 2022.02.18 |
상수(static final) (0) | 2022.02.14 |
댓글