본문 바로가기
Java

[자바 스터디] #12 - 애노테이션

by zannew 2021. 3. 1.

 목표

자바의 애노테이션에 대해 학습하세요.

▣ 학습할 내용

 

▶ 12-1 애노테이션 정의하는 방법

▷ 애노테이션이란?

프로그램의 소스코드 안에 다른 프로그램을 위한 정보를 미리 약속된 형식으로 포함시킨 것이 바로 애노테이션이다. 애노테이션은 주석(comment)처럼 프로그래밍 언어에 영향을 미치지 않으면서도 다른 프로그램에게 유용한 정보를 제공할 수 있다는 장점이 있다.

※ 참고로 애노테이션(annotation)의 뜻은 주석, 주해, 메모라는 뜻을 가지고 있다.

 

▷ 자바에서 제공하는 표준 애노테이션과 메타 애노테이션

애노테이션설명
@Override컴파일러에게 오버라이딩하는 메서드라는 것을 알림
@Deprecated앞으로 사용하지 않을 것을 권장하는 대상에 붙임
@SuppressWarnings컴파일러의 특정 경고메시지가 나타나지 않게 해줌
@SafeVarargs제네릭스 타입의 가변인자에 사용(1.7버전)
@FunctionalInterface함수형 인터페이스라는 것을 알림(1.8버전)
@Nativenative메서드에서 참조되는 상수 앞에 붙임(1.8버전)
@Target*애노테이션이 적용가능한 대상을 지정하는데 사용
@Documented*애노테이션 정보가 javadoc으로 작성된 문서에 포함되게 함
@Inherited*애노테이션이 자손 클래스에 상속되도록 함
@Retention*애노테이션이 유지되는 범위를 지정하는데 사용
@Repeatable*애노테이션을 반복해서 적용할 수 있게 함(1.8버전)

※ *가 붙은 애노테이션은 메타 애노테이션

 

 

▷ 애노테이션 정의하는 방법

새로운 애노테이션을 정의하는 방법은 다음과 같다. '@'기호를 붙이는 것만 제외하곤 인터페이스 정의하는 것과 동일하다. 

public @interface 애노테이션이름 {
	타입 요소이름();	// *애노테이션의 요소를 선언한다.
}

참고로 자주 사용하는 @Override의 경우 '@Override'는 애노테이션이고 'Override'는 애노테이션의 타입이라고 할 수 있다.

그럼 애노테이션의 요소는 무엇일까? 

애노테이션 내에 선언된 메서드를 '애노테이션의 요소(element)'라고 부른다. 

@interface TestInfo{
      int count();
      String testedBy();
      String[] testTools();
      TestType testType();	// enum TestType {FIRST,FINAL}
      DateTime testDate();	// 다른 애노테이션(@DateTime)을 포함할 수 있다.
}

@interface DateTime{
      String yymmdd();
      String hhmmss();
}

※ 애노테이션에도 인터페이스처럼 상수를 정의할 수 있지만, 디폴트 메서드를 정의할 수는 없다.

애노테이션의 요소는 리턴값이 있고 매개변수는 없는 추상메서드의 형태를 갖추고 있다. 상속을 통해 구현하지 않아도 되지만, 애노테이션을 적용할 때 이 요소들이 빠짐없이 값을 가지고 있어야한다. 요소의 이름이 필요하므로 순서는 관계없다. 

 

 

▶ 12-2 @Retention

'@Retention'은 애노테이션이 유지(retention)되는 기간을 지정하는데 사용된다. 애노테이션 유지 정책(retention policy)의 종류는 다음과 같다.

정책의미
RetentionPolicy.SOURCE소스 파일에만 존재. 클래스파일에는 존재하지 않음.
RetentionPolicy.CLASS클래스 파일에 존재. 실행시에 사용불가. 기본값
RetentionPolicy.RUNTIME클래스 파일에 존재. 실행시에 사용가능.

'@Override'나 '@SuppressWarnings'같은 애노테이션의 경우 유지 정책이 SOURCE이기 때문에 주석처럼 소스 파일 내에서만 쓰인다. 반면 '@FunctionalInterface' 역시 컴파일러가 체크하는 애노테이션이지만, 실행 시에도 사용되므로 유지 정책이 RUNTIME이다. 유지 정책이 RUNTIME이면, 실행 시 Reflection을 통해 클래스 파일에 저장된 애노테이션 정보를 읽어서 처리할 수 있다.

 

▶ 12-3 @Target

 

'@Target'은 애노테이션이 적용가능한 대상을 지정하는데 사용된다. 어떤 애노테이션을 정의한다고 했을 때, 이 애노테이션에 적용할 수 있는 대상을 '@Target'으로 지정할 수 있다. 여러 개의 값을 지정할 경우 배열처럼 중괄호{ }를 사용한다.

@Target({TYPE, FIELD, METHOD, PARAMETER})
@Retention(RetentionPolicy.SOURCE)
public @interface AnnoExample{

	String[] value();
}

 

 

▷ 지정할 수 있는 애노테이션 적용대상의 종류

대상 타입의미
ANNOTATION_TYPE애노테이션
CONSTRUCTOR생성자
FIELD필드(멤버변수, enum상수) - 기본형
LOCAL_VARIABLE지역변수
METHOD메서드
PACKAGE패키지
PARAMETER매개변수
TYPE타입(클래스, 인터페이스, enum)
TYPE_PARAMETER타입 매개변수(1.8버전)
TYPE_USE타입이 사용되는 모든 곳(1.8버전) - 참조형

 

 

▶ 12-4 @Documented(메타 애노테이션 of 표준 애노테이션)

 

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

 

 

▶ 12-5 애노테이션 프로세서

 

애노테이션 프로세서는 런타임 시 Reflection을 사용하지 않고, 컴파일 시 애노테이션 정보를 가지고 소스코드를 분석하고 생성, 처리하는 작업을 할 수 있는 기능(훅)이다. (훅은 뭐지..?)

대표적인 예로 롬복(lombok) 라이브러리가 있다. 롬복 라이브러리는 애노테이션 기반으로 컴파일 시 바이트 코드를 생성해주는 라이브러리이다. 

롬복 라이브러리에서 가장 많이 사용하는 애노테이션 중 하나인 '@Getter'와 '@Setter'의 경우 바이트코드를 살펴보면 컴파일 시 자동으로 getter와 setter코드가 생성된 것을 확인할 수 있다.

 

lombok @Getter, @Setter 바이트코드 예시

 

 

 

 

 

 

백기선님의 자바 라이브 스터디 커리큘럼을 따라 공부하고 있습니다. 

잘못된 점이나 보충할 부분이 있으면 코멘트 남겨주세요

작은 조언이 저에겐 성장의 원동력이 됩니다 :-)

댓글