자바 기본 12. 애노테이션

장난·2021년 6월 14일
0

자바 기본

목록 보기
12/15
post-thumbnail

12주차 과제: 애노테이션


📌 목표

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


📌 학습할 것

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

📜 시작에 앞서

  • 백기선 님의 라이브 스터디(2020년 11월부터 2021년 3월까지) 커리큘럼을 따라 진행한 학습입니다
  • 뒤늦게 알게 되어 스터디 참여는 못했지만 남아있는 스터디 깃허브 주소유튜브 영상을 참고했습니다

✏️ 애노테이션이란?

  • 애노테이션: 프로그램에게 추가적인 정보를 제공하는 메타데이터
    • 메타데이터: 데이터에 대한 데이터
  • 애노테이션 용도
    • 컴파일러에게 정보 제공 - 주석을 이용하여 컴파일러가 에러를 체크하거나 무시하게 할 수 있다
    • 컴파일 타임 및 배포 타임 처리 - 소프트웨어 개발 툴이 코드, xml파일, jar 압축 파일 등을 자동으로 생성할 수 있다
    • 런타임 처리 - 일부 애노테이션은 런타임에 특정 기능을 위한 정보 제공

표준 애노테이션

  • 자바에서 기본적으로 제공하는 애노테이션
애너테이션설명
@Override컴파일러에게 해당 메서드는 오버라이딩하는 것이란 정보 제공
@Deprecated클라이언트에게 사용하지 않을 것을 권한다는 정보 제공
@SuppressWarnings컴파일러에게 특정 경고메시지 나타내지 않도록 정보 제공
@SafeVarargs클라이언트에게 제네릭 타입의 가변인자 사용에 대한 정보 제공
@FunctionalInterface함수형 인터페이스 사용에 대한 정보 제공
@Nativenative메서드에서 참조되는 상수라는 정보 제공

메타 애너테이션설명
@Target애너테이션이 적용가능한 대상에 대한 정보 제공
@Documented애너테이션 정보가 javaodc 문서에 포함되기 위한 정보 제공
@Inherited애너테이션이 서브 클래스에 상속되기 위한 정보 제공
@Retention애너테이션이 유지 되는 기간에 대한 정보 제공
@Repeatable애너테이션이 한 대상에 여러 번 적용될 수 있도록 정보 제공

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


@interface

  • 애노테이션 타입 선언을 위한 키워드 interface 선언과 구분하기 위해 @를 붙인다
  • 애노테이션은 java.lang.annotation.Annotation를 확장하며, Annotation을 수동으로 확장한다고 해서 애노테이션이 되지는 않는다
@interface MyAnnotation{
    ...
}

애노테이션 필드

  • 애노테이션 필드는 추상 메서드와 비슷한 애너테이션 요소(element)로 구성되며, 인터페이스 처럼 상수를 정의할 수도 있다

애너테이션 요소

  • 추상 메서드와 형태가 같으나 추가적인 규칙이 적용된다
    • 요소의 타입(리턴 타입)은 기본형, String, enum, 애너테이션, Class만 가능
    • 메서드에 파라미터 받기 불가
    • 예외를 선언 불가
    • 요소의 타입에 타입 파라미터 사용 불가
  • 애너테이션을 적용할 때 요소의 값을 모두 지정해줘야 한다
    • 적용시 요소이름 = 적용값 방식
    • 이때 클라이언트가 모두 직접 적용하지 않을 수 있게 요소에 default 값을 줄 수 있다
      • 타입 요소이름() default "DEFAULT"
      • null 은 기본값으로 불가
    • 요소이름이 value일 때 요소이름 생략하여 값 지정 가능
      • @MyAnnotation("요소이름 생략 가능")

📑 @Retention

  • 애노테이션이 유지(retention) 되는 기간에 대한 정보 설정
  • 이를 위한 속성으로 RetentionPolicy가 있는데, 여기에는 SOURCE CLASS RUNTIME이 있다

RetentionPolicy


RetentionPolicy유지 기간
SOURCE소스 파일까지 유지
CLASS(default)클래스 파일까지 유지
RUNTIME런타임까지 유지

  • SOURCE

    • 소스 파일까지 애노테이션 정보를 유지하며, 컴파일 이후 클래스 파일에는 남아있지 않다

    • 주로 컴파일러에게 정보 제공

    • 클래스 파일에 애노테이션 정보가 필요 없는 경우 예시

      • @Override, @SupperessWarnings 컴파일러의 에러 체크에 대한 정보를 주는 경우

      • lombok@Getter 처럼 클래스 파일에 바이트코드를 생성해주고 애노테이션이 역할을 다하고 더 이상 해당 정보가 필요 없는 경우

  • CLASS

    • 클래스 파일에 애노테이션 정보가 저장되지만, JVM에 로딩되지 않기 때문에 JVM에는 해당 정보가 없다
    • SOURCE와 차이점은 클래스 파일에 정보가 남는 다는 것, 사용 상황 예시
      • 라이브러리 jar 파일(Download Sources 옵션은 논외)에는 소스 파일이 포함되지 않으므로 여기서 런타임에 영향을 미치지 않고 애노테이션 정보를 넘기고 싶을 때
  • RUNTIME

    • 애노테이션 정보가 메모리까지 올라가므로, 실행 동안에도 정보를 사용할 수 있다
    • Reflection API 등을 통해 애노테이션 정보를 알 수 있다는 것
      • 리플렉션은 클래스로더가 읽어들인 정보 기반으로 메모리에 들어 있는 정보를 읽는 것
    • 주로 클라이언트에게 정보 제공

참고: 기본기를 쌓는 정아마추어 코딩블로그: 아무 관심 없던 @Retention 어노테이션 정리(RetentionPolicy SOURCE vs CLASS vs RUNTIME)


📑 @Target

  • 애노테이션이 적용가능한 대상에 대한 정보 설정
  • 속성 값으로는 java.lang.annotation.ElementType 열거형에 정의된 상수 사용 가능
  • 속성 값 여러개 지정할 때는 {} 사용

ElementType

상수설명
ANNOTATION_TYPE애노테이션
CONTRUCTOR생성자
FIELD필드(enum 상수 포함)
LOCAL_VARIABLE지역변수
METHOD메서드
PACKAGE패키지
PARAMETER파라미터
TYPE클래스, 인터페이스(애노테이션 타입 포함), enum
TYPE_PARAMETER타입 파라미터 (JDK 1.8)
TYPE_USE타입이 사용되는 곳 (JDK 1.8)
  • ElementType.TYPE인 마커 애노테이션을 작성하고 있다면, 정말 애노테이션으로 구현해야 할지, 마커 인터페이스로 구현했을 시와 비교해 고민
    • 마커 애노테이션: 정의된 요소가 없는 애노테이션

📑 @Documented

  • 애노테이션 정보가 javaodc 문서에 포함되기 위한 정보 설정
    • 클래스나 메서드에 대한 애노테이션은 기본적으로 javadocs에 포함되지 않는다
package com.servlets;
import java.lang.annotation.*;

@Unfinished("Just articleware")
@Documented
public @interface Unfinished { ...

출저 : oracle: Making the Most of Java's Metadata, Part 2: Custom Annotations

  • 다음과 같은 코드 작성시 @Unfinished 가 붙은 메서드나 클래스는 javadocs에 @Unfinished에 대한 정보가 포함되는 것

📑 애노테이션 프로세서

  • 애노테이션 프로세서 : 컴파일 타임에 특정 애노테이션을 애너테이션이 나타내는 정보에 따라 적절히 처리하는 주체


  • 관련 이해가 필요하거나 심심할 때 위 링크 중 하나 선택해 프로세서 만들어보기

0개의 댓글