Java 애너테이션

2022. 11. 23. 20:00·Java

애너테이션

학습주제

  • 애너테이션 정의하는 방법
  • @Retention
  • @Target
  • @Documented
  • 애너테이션 프로세서

애너테이션

  • 애너테이션은 주석이라는 뜻
  • 애너테이션과 일반적인 주석이 다른 점
    • 일반 주석은 사람을 위한 것이고, 애너테이션은 컴파일러를 위해 작성한 주석
  • 문법 오류를 체크할 수 있도록 힌트 제공. 예) @Override
  • 빌드 시 코드 자동 생성. 예) 롬복 라이브러리
  • 런타임 시점에 참고해서 특정 동작을 하도록 할 때 사용. 예) 스프링의 aop

표준 애너테이션

  • 자바에서 기본으로 제공하는 애너테이션
    1. 자바코드 작성시 사용되는 애너테이션
    2. 메타 애너테이션 : 애터테이션을 정의할 때 사용하는 애너테이션. 애너테이션에 붙이는 애너테이션

@Retention

  • 애너테이션이 유지되는 기간을 지정하는데 사용된다.
  • 애너테이션의 유지 정책의 종류
    • SOURCE : 소스 파일에만 존재. 클래스파일에는 존재하지 않음.
    • CLASS : 클래스 파일에 존재. 실행 시에 사용 불가. 기본값
    • RUNTIME : 클래스 파일에 존재. 실행 시에 사용 가능.
  • 애너테이션 RetentionPolicy 예시
      @Documented
      @Retention(RetentionPolicy.RUNTIME)
      @Target(ElementType.TYPE)
      public @interface FunctionalInterface {}

SOURCE

  • 컴파일러가 사용하는 애너테이션
  • 컴파일러에서 사용하는 retention policy이므로 사용자가 정의할 일이 없다.
  • @Override, @SuppressWarnings
  • 지역변수에 붙은 애너테이션은 컴파일러만 인식할 수 있으므로, 유지정책이 RUNTIME인 애터네이션을 붙여도 실행 시에는 인식되지 않는다.

RUNTIME

  • 실행 시에 리플렉션을 통해 클래스 파일에 저장된 애너테이션의 정보를 읽어서 처리할 수 있다.

CLASS

컴파일러가 애너테이션의 정보를 클래스 파일에 저장한다. 하지만 클래스 파일이 JVM에 로딩될 때는 애너테이션의 정보가 무시되어 실행 시에 애너테이션에 대한 정보를 얻을 수 없다.
그래서 유지 정책의 기본값임에도 잘 사용되지 않는다.

@Target

  • 애너테이션이 적용 가능한 대상을 지정하는데 사용
  • 여러 개 지정할 경우 {}를 사용
대상 타입 의미
ANNOTATION_TYPE 애너테이션, 메타애노테이션이 됨
CONSTRUCTOR 생성자
FIELD 멤버변수, enum 상수, 기본형에 사용됨
LOCAL_VARIABLE 지역변수
METHOD 메서드
PACKAGE 패키지
PARAMETER 매개변수
TYPE 타입(클래스,인터페이스,enum)선언시 애너테이션 붙일 수 있다.
TYPE_PARAMETER 타입 매개변수(Java8)
TYPE_USE 타입이 사용되는 모든 곳(Java8), 해당 타입의 변수를 선언할 때 붙일 수 있다. 참조형에 사용됨
  • FIELD는 기본형에, TYPE_USE는 참조형에 사용된다.
  • import static java.lang.annotation.ElementType.*; @Target({FIELD, TYPE, TYPE_USE}) public @interface MyAnnotation{} @MyAnnotation //TYPE public class MyClass { @MyAnnotation //FIELD int i; @MyAnnotation //TYPE_USE MyClass myClass; }
  • Target 예시
  • @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, MODULE}) @Retention(RetentionPolicy.SOURCE) public @interface SuppressWarnings { String[] value(); //애너테이션 요소 }

@Documented

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

  • @Documented 붙은 것과 붙지 않은 표준 애너테이션
    //Override
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.SOURCE)
    public @interface Override {
    }
    

//SafeVarargs
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD})
public @interface SafeVarargs {}



---

## 애너테이션 정의하는 방법

```java
@interface 애너테이션이름 {
    타입 요소이름(); //애너테이션의 요소 선언.
}

애너테이션의 요소

  • 애너테이션 내에 선언된 메서드
  • 반환값이 있고 매개변수는 없는 추상 메서드의 형태를 가지고, 상속을 통해 구현하지 않아도 된다.
  • 애너테이션을 적용할 때 이 요소들의 값을 빠짐없이 지정해주어야 한다.
  • 애너테이션 요소는 기본값을 가질 수 있고, 값 미지정시 기본값이 사용된다.
  • 요소가 단 하나이고. 요소명이 value()이면 적용할 때 요소명을 생략할 수 있다.
  • 마커 애너테이션 : 요소가 하나도 정의되지 않은 애너테이션

 

  • 애너테이션 요소 규칙
    • 요소 타입은 기본형, String, enum, 애너테이션, Class 만 허용
    • ()안에 매개변수 선언할 수 없다
    • 예외 선언할 수 없다
    • 요소를 타입 매개변수로 정의할 수 없다.
    @interface TestInfo {
        int count() default 1; //기본값 1
        String testedBy();
        String[] testTools();
        TestType testType(); //enum TestType {FIRST, FINAL}
        DateTime testDate(); //다른 애너테이션
    }

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

    //애너테이션 요소 적용 예시
    @TestInfo(
        count = 3, testedBy = "Hong",
        testTools = {"JUnit", "AutoTester"},
        testType = TestType.FIRST,
        testDate = @DateTime(yymmdd = "221101", hhmmss = "235959")
    )
    public class NewClass { }

java.lang.annotation.Annotation

  • 모든 애너테이션의 조상
  • 애너테이션은 상속이 허용되지 안으므로 명시적으로 Annotation을 조상으로 지정할 수 없다.

애너테이션 프로세서

  • 컴파일 타임에 애노테이션 정보를 참고하여 코드를 분석하고 생성하는 등의 작업을 할 수 있는 기능
  • lombok 라이브러리는 대표적인 어노테이션 프로세서
    • 롬복을 사용하고 클래스 파일을 열어보면 만들지도 않은 메소드가 추가된다. 이것은 컴파일할 때 생성된다.
    • 예) 롬복의 @Setter : setter 메서드가 클래스 파일에 생성되어 있다.
  • 인텔리제이에서 애너테이션 프로세서 설정 : setting/Build,Execution,Deployment/Compiler/Annotation Processors/Enable annotation processing
  • annotation processor의 장점은 코드 분석, 생성의 동작이 '컴파일 타임'에 이루어지기 때문에 런타임에 비용이 추가되지 않는다는 것.

annotation processor 동작 원리

  • 컴파일러는 코드에 annotation processor가 있는 것을 어떻게 아는 것일까?
    • 참고 : https://xxxelppa.tistory.com/205?category=858435
  • Annotation Processor 를 등록하려면,
    1. META-INF 디렉토리 하위에 services 디렉토리를 만들고
    2. javax.annotation.processing.Processor 라는 파일을 만들고
    3. 그 안에 AbstractProcessor 클래스를 상속받아 구현하고 있는 클래스의 FQCN 을 작성

참고자료

  • 자바의 정석
  • https://xxxelppa.tistory.com/205?category=858435
저작자표시 비영리 변경금지 (새창열림)

'Java' 카테고리의 다른 글

필요없는 검사 예외 사용은 피하라  (0) 2023.01.15
Java 제네릭  (0) 2022.11.28
Java enum  (0) 2022.11.04
Java 클래스  (0) 2022.09.30
Java 예외 처리  (0) 2022.09.29
'Java' 카테고리의 다른 글
  • 필요없는 검사 예외 사용은 피하라
  • Java 제네릭
  • Java enum
  • Java 클래스
devstep
devstep
웹 백엔드 개발자
  • devstep
    개발 여정
    devstep
  • 전체
    오늘
    어제
    • 분류 전체보기 (89)
      • Java (24)
      • Spring Framework (16)
        • Spring (13)
        • JPA (3)
      • Database (8)
        • RDBMS공통 (1)
        • MySQL (6)
        • Redis (0)
        • Oracle (1)
      • Concept (13)
        • 테스트코드 (4)
        • 클린코드 (2)
        • 성능테스트 (4)
        • 설계 (1)
        • 인증 (1)
        • REST API (1)
      • git (2)
      • Intellij (4)
      • Computer Science (3)
        • 네트워크 (1)
        • 자료구조 (1)
        • 보안 (1)
      • Essay (17)
        • Learning Essay (10)
        • WIL (7)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    보안
    aggregate
    storageEngine
    bean
    tdd
    단위테스트
    JVM
    applicationcontext
    nofile
    비대칭암호화
    테스트코드
    클린코드
    JMeter
    DDD
    인텔리제이실행에러
    성능테스트
    자바메모리모델
    component
    JavaMemoryModel
    부하테스트
    nginx
    블록암호화
    linux
    대칭암호화
    부하테스트도구
    innodb
    seed
    springsecurity
    ClusteredIndex
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
devstep
Java 애너테이션
상단으로

티스토리툴바