Annotation(애너테이션)

박윤택·2022년 5월 20일
2

JAVA

목록 보기
9/14

🧨 용도

annotation은 주석처럼 프로그래밍 언어에 영향을 미치지 않으면서 유용한 정보를 제공한다. 에너테이션의 역할을 살펴보면 다음과 같다.

  • 컴파일러에게 문법 에러를 체크하도록 정보를 제공
  • 프로그램을 빌드할때 코드를 자동으로 생성할 수 있도록 정보 제공
  • 런타임에 특정 기능을 실행하도록 정보를 제공

🎭 종류

  • 표준 애너테이션 : 자바에서 기본적으로 제공
표준 에너테이션설명
@Override컴파일러에게 메서드를 오버라이딩하는 것이라고 알려줌
@Deprecated앞으로 사용하지 않을 대상을 알릴때 사용
@FunctionalInerface함수형 인터페이스라는 것을 알려줌
@SuppressWarning컴파일러가 경고메시지를 나타내지 않음

  • 메타 애너테이션 : 애너테이션에 붙이는 애너테이션
메타 에너테이션설명
@Target애너테이션을 정의할때 정의 대상을 지정할때 사용
@Documented애너테이션 정보를 javadoc으로 작성된 문서에 포함
@Inherited애너테이션이 하위클래스에 상속되도록 설정
@Retention애너테이션의 유지 기간을 설정
@Repeatable애너테이션을 반복해서 적용할 수 있게 함

🎵 표준 애너테이션

@Override와 @Deprecated는 코드를 짜면서 자주 사용 또는 마주쳤지만 @FunctionalInterface와 @SuppressWarning 애너테이션은 눈에 익숙치 않아 따로 정리 하려 한다.


@FunctionalInterface

함수형 인터페이스를 선언할때 올바르게 선언했는지 확인하는 용도이며 @FunctionalInterface를 붙이지 않아도 함수형 인터페이스를 선언할 수 있다. 하지만 함수형 인터페이스는 하나의 추상메서드만 있어야하므로 이를 사전에 검증할 수 있다.


@SuppressWarning

애너테이션설명
@SuppressWarning("all")모든 경고를 억제
@SuppressWarning("deprecation")Deprecated 메서드 사용할 경우 경고 억제
@SuppressWarning("fallthrough")switch 문에서 break 없을때 생기는 경고 억제
@SuppressWarning("finally")finally 관련 경고 억제
@SuppressWarning("null")null 관련 경고 억제
@SuppressWarning("uncheched")검증되지 않은 연산자 관련 경고 억제
@SuppressWarning("unused")사용하지 않은 코드 관련 경고 억제

🎼 메타 애너테이션

"애너테이션에 붙이는 애너테이션"


@Target

"애너테이션의 적용 범위 설정"

대상 타입적용 범위
ANNOTATION_TYPE애너테이션
CONSTRUCTOR생성자
FIELD필드(멤버 변수, 열거형 상수)
LOCAL_VARIABLE지역 변수
METHOD메서드
PACKAGE패키지
PARAMETER매개 변수
TYPE타입(클래스, 인터페이스, 열거형)
TYPE_PARAMETER타입 매개변수
TYPE_USE타입이 사용되는 모든 대상
import static java.lang.annotation.ElementType.*;
import java.lang.annotation.Target;

@Target(FIELD)
//@Target({FIELD, METHOD, TYPE_USE}) // 타겟 여러개 설정
public @interface Meta {
    
}

class Main {
    @Meta
    int i;
    
//    @Meta // Field 에만 애너테이션 적용 가능
//    void test(){}
}

@Inherited

하위 클래스가 애너테이션을 상속받도록 한다. @Inherited 애너테이션을 부모 클래스에 적용하고 이를 하위 클래스에서 상속받는다면 정의한 애너테이션이 적용된다.

import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
@Inherited
@interface Test {
}

@Test
class Main {
    int a;
}

class Sub extends Main {
    int b;
}

public class Meta {
    public static void main(String[] args) {
        System.out.println(new Main().getClass().getAnnotation(Test.class)); // @annotationTest.Test()
        System.out.println(new Sub().getClass().getAnnotation(Test.class)); // @annotationTest.Test()
    }
}

@Inherited 애너테이션을 쓴 Main을 상속받은 Sub에서도 애너테이션이 동일하게 적용되고 있음을 확인할 수 있다.


@Retention

애너테이션이 유지되는 기간을 지정

유지 정책설명
SOURCE.java 파일까지는 애너테이션이 존재, 컴파일 되어 클래스 파일이 되면 사라짐
CLASS.class 파일까지는 애너테이션이 존재, 런타임에서 사라짐
RUNTIME런타임 실행시까지 애너테이션이 남아 있음

@Repeatable

@Repeatable 애너테이션이 붙은 애너테이션을 여러번 작성할 수 있다.
단, 여려번 애너테이션을 붙일 경우 애너테이션들을 하나로 묶어주는 애너테이션도 별도로 작성해야 한다.

@interface NamesTest {  // 여러개의 NameTest애너테이션을 담을 컨테이너 애너테이션 ToDos
    NameTest[] value(); // NameTest애너테이션 배열 타입의 요소를 선언. 이름이 반드시 value여야 함  
}

@Repeatable(NamesTest.class)
@interface NameTest {
	String value();
}

@NameTest("name")
@NameTest("test") 
class Test {
}

🧣 사용자 정의 애너테이션

애너테이션을 정의하는 방법은 인터페이스를 정의하는 것과 비슷하다.

@interface 애너테이션명 {
	타입 요소명(); // 애너테이션 요소를 선언
}

예시

import java.lang.annotation.*;

@Target(ElementType.FIELD)//애너테이션이 적용 가능한 대상을 FIELD로 지정
@Retention(RetentionPolicy.RUNTIME)//코드 실행시 까지 애너테이션이 유지
@Documented //애너테이션 정보를 javadoc으로 작성된 문서에 포함
public @interface Seasons { // 계절을 지정해주는 애너테이션을 작성합니다.
    enum Season {SPRING, SUMMER, AUTUMN, WINTER}

    Framework season() default Season.SPRING;
}

public class Today {
	@Seasons(season = Seasons.Season.SPRING)
    private String season;
}

0개의 댓글