[JAVA 스터디] 12주차 : @Annotation

codename_hee·2021년 12월 7일
0

학습할 것

  • 어노테이션 정의하는 방법
  • @retention
  • @target
  • @documented
  • 어노테이션 프로세서

먼저 알고가기

어노테이션이란?

  • 프로그램의 소스코드 안에 다른 프로그램을 위한 정보를 미리 약속된 형식으로 포함시킨 것
  • 메타데이터. 어플리케이션이 처리하는 데이터가 아닌 컴파일 과정과 실행 과정에서 코드를 어떻게 컴파일하고 처리할 것인지를 알려주는 정보

어노테이션의 용도

  • 컴파일러에게 코드 문법 에러를 체크하도록 정보를 제공
    소프트웨어 개발 툴이 빌드나 배치 시 코드를 자동으로 생성할 수 있도록 정보를 제공
  • 실행 시(런타임 시)특정 기능을 실행하도록 정보를 제공

특징

  • 주석처럼 프로그래밍 언어에 영향을 미치지 않으면서도 다른 프로그램에게 유용한 정보를 제공할 수 있다는 장점이 있다.
    - 예를 들어, 소스코드 중 특정 메서드만 테스트하길 원할 경우, 해당 코드에 '@Test' 라는 어노테이션을 붙이면 테스트 프로그램에게 해당 메서드는 테스트를 해야한다는 것을 알릴 뿐 메서드가 포함된 전체 프로그램 자체에는 해당 어노테이션이 아무런 영향을 미치지 않는다.
  • JDK에서 제공하는 표준 어노테이션은 주로 컴파일러를 위한 것으로 컴파일러에게 유용한 정보를 제공
  • 새로운 어노테이션을 정의할 때 사용하는 메타 어노테이션도 제공

어노테이션의 종류

  • Built-in Annotation : 자바에서 기본적으로 제공하는 어노테이션
  • Meta Annotation : 커스텀 어노테이션을 만들수 있게 제공된 어노테이션.
  • Custome Annotation : 사용자가 직접 정의한 어노테이션

1. Built-in Annotation

2. Meta Annotation

어노테이션을 정의하는 방법

  • 인터페이스를 정의하는 것과 유사하게 다음과 같이 @interface를 사용해서 정의한다.
public @interface AnnotaionName{
}
  • 엘리먼트(element)를 멤버로 가질 수 있다.
public @interface AnnotationName {
	String elementName1(); #=> 값이 없으므로 반드시 값을 기술해야 함
    int elementName2() default 5; #=> 디폴트 값이 있으므로 생략 가능
}
<위의 어노테이션을 사용할 >
@AnnotationName(elementName1 = "값", elementName2 = 3);
또는
@AnnotationName(elementName1 = "값");
<기본 엘리먼트가 포함된 어노테이션 선언>
public @interface AnnotationName {
	String value(); #=> 기본 element 선언
    int elementName() default 5;
}
<Value 엘리먼트를 가진 어노테이션을 적용하는 방법>
@AnnotationName("값"); #=> value자리에 값이 설정되는 것

#value엘리먼트와 다른 엘리먼트의 값을 동시에 주고싶다면
@AnnotationName(value = "값", elementName=3);
  • 메타 어노테이션을 사용하여 어노테이션이 적용되는 대상이나 유지기간 등을 지정한다.
  • '@'를 이용하여 선언한다.

메타 어노테이션이란?

  • 어노테이션을 위한 어노테이션
  • 어노테이션에 붙이는 어노테이션
어노테이션설명
@Target어노테이션이 적용가능한 대상을 지정하는데 사용한다.
@Documented어노테이션 정보가 javadoc으로 작성된 문서에 포함되게 한다.
@Inherited어노테이션이 자손 클래스에 상속되도록 한다.
@Retention어노테이션이 유지되는 범위를 지정하는데 사용한다.
@Repeatable어노테이션을 반복해서 적용할 수 있게 한다. (JDK 1.8)

@Retention

  • 어노테이션이 유지되는 기간을 지정하는데 사용된다.

<어노테이션의 유지 정책>

유지 정책의미
SOURCE소스 파일에만 존재. 클래스파일에는 존재하지 않음.
CLASS클래스 파일에 존재. 실행시에 사용불가. 기본값
RUNTIME클래스 파일에 존재. 실행시에 사용가능.
  • SOURCE : 컴파일러가 사용하는 어노테이션. 컴파일러를 직접 작성할 것이 아니면 해당 유지정책은 필요 없다.
  • RUNTIME : 실행 시에 리플렉션(reflection)을 통해 클래스 파일에 저장된 어노테이션의 정보를 읽어서 처리할 수 있다.
    *Reflection : 런타임 시에 클래스의 메타 정보를 얻는 기능. 클래스의 필드가 무엇인지 어떤 생성자를 가지고 있는지 어떤 메소드를 가지고 있는지 적용된 어노테이션이 무엇인지를 알아내는 것.
    => 런타임 시에 어노테이션 정보를 얻으려면 어노테이션 유지 정책을 RUNTIME으로 해야 한다.
  • CLASS : 컴파일러가 어노테이션의 정보를 클래스 파일에 저장할 수 있게는 하지만 클래스 파일이 JVM에 로딩될 때에는 어노테이션의 정보가 무시되어 실행 시에 어노테이션에 대한 정보를 얻을 수 없다.

@Target

  • 어노테이션이 적용가능한 대상을 지정하는데 사용된다.
<@SuppressWarnings 어노테이션을 정의하는 >
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
	String[] value();
}
  • '@Target'으로 지정할 수 있는 어노테이션 적용대상의 종류
대상 타입의미
ANNOTATION_TYPE어노테이션
CONSTRUCTOR생성자
FIELD필드(멤버변수, ENUM상수)
LOCAL_VARIABLE지역변수
METHOD메서드
PACKAGE패키지
PARAMETER매개변수
TYPE타입(클래스, 인터페이스, ENUM)
TYPE_PARAMETER타입 매개변수(JDK 1.8)
TYPE_USE타입이 사용되는 모든 곳(JDK 1.8)
  • TYPE : 타입을 선언할 때 어노테이션을 붙일 수 있다는 뜻
  • TYPE_USE : 해당 타입의 변수를 선언할 때 붙일 수 있다는 뜻

@Documented

  • 어노테이션에 대한 정보가 javadoc으로 작성한 문서에 포함되도록 한다.
  • 자바에서 제공하는 기본 어노테이션 중에 '@Override', '@SuppressWarnings'를 제외하고는 모두 이 메타 어노테이션이 붙어 있다.

위의 세가지 어노테이션이 적용된 코드의 예시

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface {}

어노테이션 프로세서

  • 컴파일 타임에 어노테이션을 분석하는 단계.
  • 어노테이션을 이용하여 새로운 리소스르 생성해낼 수 있는 방법 및 과정

프로세싱 과정

  1. 어노테이션 클래스를 생성한다.
  2. 어노테이션 파서 클래스(Annotation Parser Class)를 생성한다.
  3. 어노테이션을 사용한다.
  4. 컴파일하면, 어노테이션 파서가 어노테이션을 처리한다.
  5. 자동 생성된 클래스가 빌드 폴더에 추가된다.
profile
진정한 개발자로 가는 길

0개의 댓글