▣ 목표
자바의 애노테이션에 대해 학습하세요.
▣ 학습할 내용
- 애노테이션 정의하는 방법
- @retention
- @target
- @documented
- 애노테이션 프로세서
▶ 12-1 애노테이션 정의하는 방법
▷ 애노테이션이란?
프로그램의 소스코드 안에 다른 프로그램을 위한 정보를 미리 약속된 형식으로 포함시킨 것이 바로 애노테이션이다. 애노테이션은 주석(comment)처럼 프로그래밍 언어에 영향을 미치지 않으면서도 다른 프로그램에게 유용한 정보를 제공할 수 있다는 장점이 있다.
※ 참고로 애노테이션(annotation)의 뜻은 주석, 주해, 메모라는 뜻을 가지고 있다.
▷ 자바에서 제공하는 표준 애노테이션과 메타 애노테이션
애노테이션 | 설명 |
@Override | 컴파일러에게 오버라이딩하는 메서드라는 것을 알림 |
@Deprecated | 앞으로 사용하지 않을 것을 권장하는 대상에 붙임 |
@SuppressWarnings | 컴파일러의 특정 경고메시지가 나타나지 않게 해줌 |
@SafeVarargs | 제네릭스 타입의 가변인자에 사용(1.7버전) |
@FunctionalInterface | 함수형 인터페이스라는 것을 알림(1.8버전) |
@Native | native메서드에서 참조되는 상수 앞에 붙임(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코드가 생성된 것을 확인할 수 있다.

백기선님의 자바 라이브 스터디 커리큘럼을 따라 공부하고 있습니다.
잘못된 점이나 보충할 부분이 있으면 코멘트 남겨주세요
작은 조언이 저에겐 성장의 원동력이 됩니다 :-)
'Java' 카테고리의 다른 글
[자바 스터디] #14 - 제네릭 (0) | 2021.03.10 |
---|---|
[자바 스터디] #10 - 멀티쓰레드 프로그래밍 (0) | 2021.02.28 |
[자바 스터디] #9 - 예외처리 (0) | 2021.02.18 |
[자바 스터디] #7 - 패키지 (0) | 2021.02.17 |
[자바 스터디] #8 - 인터페이스 (1) | 2021.02.16 |
댓글