Annotation

  • 프로그램 소스코드 안에 다른 프로그램을 위한 정보를 미리 약속된 형식으로 포함시킨것
  • 주석처럼 프로그래밍 언어에 영향을 미치지 않으면서도 다른 프로그램에게 유용한 정보를 제공함
  • 일종의 메타데이터
  • JDK1.5부터

종류

표준(내장) 어노테이션

  • 메타 어노테이션을 제외한 일반적인 어노테이션
  • 주로 컴파일러에게 유용한 정보를 제공하기 위함
  • @Override, @SuppressWarnings, @Deprecated, @Repeatable(1.7), @FunctionalInterface(1.7),...

메타 어노테이션

  • 어노테이션을 위한 어노테이션
  • 어노테이션 정의시 사용
  • @Documented, @Target, @Retention, @Inherited,...

장점? 특징?

  • 보통 xml 설정파일을 프로그램 구동되는 시점에 읽음
    • xml 파일 내용: 이런 객체 만들어야함. 어쩌구저쩌구. 시키는 내용들
  • 그 파일이 시키는대로 프로그램이 돌음
  • 하지만 xml없어도 어노테이션있으면 그걸로 프로그램 돌 수 있음

작성 방법

@interface 어노테이션이름 {
	반환타입 타입요소이름(); 
    // 반환값이 있고 매개변수는 없는 추상메서드의 형태
    ...
}

작성 규칙

  • 요소의 타입은 기본형, String, enum, annotation, class만 허용
  • ()안에 매개변수를 선언할 수 없다.
  • 예외를 선언할 수 없다.
  • 요소의 타입에 타입 매개변수(제너릭타입문자)를 사용할 수 없다.

예시

1단계: 어노테이션 작성

  • PrintAnnotation.java
@Target(ElementType.METHOD) // annotation이 적용가능한 대상을 지정함.
@Retention(RetentionPolicy.RUNTIME) // annotation이 유지되는 기간(CLASS가 기본값)
public @interface PrintAnnotation {
	int id = 100; // 상수 선언가능. static final int id = 100;
	String value() default "-"; // 기본값을 '-'로 지정
	int count() default 20;		// 기본값을 20으로 지정
}

2단계: 메서드 모아놓은 Service 클래스

  • Service.java
public class Service {
	
	@PrintAnnotation
	public void method1() {
		System.out.println("메서드1에서 출력되었습니다람쥐.");
	}
    
	// value라는 이름의 타입요소이고 1개만 있는 경우에는 'value ='  지워도된다.
	@PrintAnnotation("%") 
	public void method2() {
		System.out.println("메서드2에서 출력되었습니다람쥐.");
	}
	
	@PrintAnnotation(value = "#", count = 25)
	public void method3() {
		System.out.println("메서드3에서 출력되었습니다람쥐.");
	}
	
}

3단계: 실행

  • AnnotationTest.java
public class AnnotationTest {
  public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {

    // 어노테이션 정보를 얻어내려고 갑자기 리플렉션 공부중..
    // reflection 기능을 이용한 메서드 실행하기
    // 선언된 메서드 목록 가져오기
    Method[] declaredMethods = Service.class.getDeclaredMethods(); 
    // 클래스객체안에 getDeclaredMethods() static메서드가 있다.
    // Service안에 declared된 메서드들 전부 들고올 수 있다.

    for (Method m : declaredMethods) {
      System.out.println(m.getName()); // 메서드명 출력 (메서드객체.getName())

                                                      // 어노테이션,인터페이스,enum,클래스 등등 다들 타입이기때문에 class객체로 정보를 관리할 수 있다.
                                                      //┌─▶ 내가 찾고자하는 어노테이션을 매개변수로. 
      for (int i = 0; i < m.getDeclaredAnnotation(PrintAnnotation.class).count(); i++) {
          System.out.print(m.getDeclaredAnnotation(PrintAnnotation.class).value()); // value값 출력: %, #
      }

      System.out.println(); // 줄바꿈 처리

      // reflection기능 이용한 메서드 실행 --> 메서드1에서 출력되었습니다람쥐 출력된 까닭
      // 방법1
      //m.invoke(new Service()); 

      // 방법2 - 아래 두줄이 new Service()랑 같은 것
      Class<Service> klass = Service.class;
      Service service = (Service) klass.newInstance(); 
      m.invoke(service);


    }
  }
}
profile
갈 길이 멀다

0개의 댓글