본문 바로가기
Java Study

@ 어노테이션 (Annotation)

by xogns93 2024. 7. 18.

어노테이션(Annotation)은 Java에서 코드에 메타데이터를 추가하는 방법입니다. 어노테이션은 컴파일러에게 지시를 내리거나, 런타임 시 특정 행동을 수행하도록 할 수 있습니다. 어노테이션은 클래스, 메소드, 필드, 매개변수 등에 붙여서 사용합니다.

 

어노테이션의 정의

어노테이션은 @ 기호로 시작하며, 다음과 같은 형태로 정의됩니다.

// 어노테이션 정의
import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
    String value();
    int number() default 0;
}

 

  • @Retention: 어노테이션의 유지 정책을 정의합니다.
    • RetentionPolicy.SOURCE: 소스 코드에서만 유효하며, 컴파일 후 제거됩니다.
    • RetentionPolicy.CLASS: 컴파일러가 클래스를 참조할 때까지 유효하며, 런타임에는 유지되지 않습니다.
    • RetentionPolicy.RUNTIME: 런타임까지 유지되며, 리플렉션을 통해 어노테이션 정보를 얻을 수 있습니다.
  • @Target: 어노테이션을 적용할 수 있는 프로그램 요소를 정의합니다.
    • ElementType.TYPE: 클래스, 인터페이스, 열거형에 적용
    • ElementType.METHOD: 메소드에 적용
    • ElementType.FIELD: 필드에 적용
    • ElementType.PARAMETER: 매개변수에 적용

자주 사용되는 어노테이션 (annotation)

@Override

  • 메소드가 상위 클래스의 메소드를 오버라이드하고 있음을 나타냅니다.
  • 잘못된 오버라이딩을 방지하는 데 유용합니다.
public class Parent {
    public void display() {
        System.out.println("Parent display");
    }
}

public class Child extends Parent {
    @Override
    public void display() {
        System.out.println("Child display");
    }
}

 

 

@Deprecated

  • 더 이상 사용되지 않는 요소임을 나타냅니다.
  • 프로그램이 @Deprecated 어노테이션이 달린 메서드, 클래스 또는 필드를 사용할 때마다 컴파일러는 경고를 생성합니다.

@SuppressWarnings

  • 컴파일러 경고를 억제합니다.
  • 특정 경고 유형을 지정하여 사용합니다.

@SafeVarargs

  • 가변 인자 메소드에서 발생하는 "unchecked" 경고를 억제합니다.

@FunctionalInterface

  • 인터페이스가 함수형 인터페이스임을 나타냅니다.
  • 함수형 인터페이스는 단 하나의 추상 메소드를 가져야 합니다

JUnit 5 어노테이션

  • @Test : 메소드가 테스트 메소드임을 나타냅니다.
  • @BeforeEach : 각 테스트 메소드가 실행되기 전에 실행됩니다.
  • @AfterEach : 각 테스트 메소드가 실행된 후에 실행됩니다.
  • @BeforeAll : 모든 테스트 메소드가 실행되기 전에 한 번 실행됩니다.
  • @AfterAll : 모든 테스트 메소드가 실행된 후에 한 번 실행됩니다.

 


메타 어노테이션 (meta-annotation)

 

다른 어노테이션에 적용되는 어노테이션을 메타 어노테이션(meta-annotation)이라고 합니다. java.lang.annotation 패키지에는 여러 메타 어노테이션 타입이 정의되어 있습니다.

 

 

@Retention @Retention 어노테이션은 표시된 어노테이션이 어떻게 저장되는지를 지정합니다:

  • RetentionPolicy.SOURCE –  표시된 어노테이션은 소스 레벨에서만 유지되며 컴파일러에 의해 무시됩니다
  • RetentionPolicy.CLASS – 표시된 어노테이션은 컴파일 시 컴파일러에 의해 유지되지만, Java 가상 머신(JVM)에 의해 무시됩니다.
  • RetentionPolicy.RUNTIME – 표시된 어노테이션은 JVM에 의해 유지되어 런타임 환경에서 사용할 수 있습니다.

@Documented @Documented 어노테이션은 지정된 어노테이션이 사용될 때마다 해당 엘리먼트들이 Javadoc 도구를 사용하여 문서화되어야 함을 나타냅니다(기본적으로 어노테이션은 Javadoc에 포함되지 않습니다). 자세한 내용은  Javadoc tools page를 참조하십시오

 

@Target @Target 어노테이션은 다른 어노테이션을 표시하여 해당 어노테이션이 적용될 수 있는 Java 엘리먼트의 종류를 제한합니다. Target 어노테이션은 다음 엘리먼트 타입 중 하나를 값으로 지정합니다:

  • ElementType.ANNOTATION_TYPE은 어노테이션 타입에 적용될 수 있습니다.
  • ElementType.CONSTRUCTOR은 생성자에게 적용될 수 있습니다.
  • ElementType.FIELD은 field or property에 적용될 수 있습니다.
  • ElementType.LOCAL_VARIABLE 은 local variable에 적용될 수 있습니다.
  • ElementType.METHOD 은 method-level annotation에 적용될 수 있습니다.
  • ElementType.PACKAGE 은 package declaration에 적용될 수 있습니다.
  • ElementType.PARAMETER 은 method의 parameters에 적용될 수 있습니다.
  • ElementType.TYPE 은 class의 엘리먼트에 적용될 수 있습니다.

@Inherited @Inherited 어노테이션은 어노테이션 타입이 슈퍼클래스로부터 상속될 수 있음을 나타냅니다. (기본적으로는 그렇지 않습니다.) 사용자가 어노테이션 타입을 조회할 때 해당 클래스에 해당 타입의 어노테이션이 없으면, 클래스의 슈퍼클래스에서 어노테이션 타입을 조회합니다. 이 어노테이션은 클래스 선언에만 적용됩니다.

 

@Repeatable @Repeatable 어노테이션은 Java SE 8에서 도입되었으며, 표시된 어노테이션을 동일한 선언 또는 타입 사용에 여러 번 적용할 수 있음을 나타냅니다. 자세한 내용은 반복 어노테이션을 참조하십시오.

 


반복 어노테이션 Repeating Annotations

 

경우에 따라 동일한 어노테이션을 선언이나 타입 사용에 적용하고자 할 때가 있습니다. Java SE 8 릴리스부터 반복 어노테이션을 사용하여 이를 수행할 수 있습니다.

 

예를 들어, 주어진 시간이나 일정에 따라 메서드를 실행할 수 있는 타이머 서비스를 사용하는 코드를 작성하고 있다고 가정해 보겠습니다. UNIX의 cron 서비스와 유사하게, 특정 시간이나 일정에 메서드를 실행하도록 타이머를 설정하고 싶습니다. 이제 매월 말일과 매주 금요일 오후 11시에 메서드 doPeriodicCleanup을 실행하도록 타이머를 설정하려고 합니다. 타이머를 설정하기 위해 @Schedule 어노테이션을 생성하고 doPeriodicCleanup 메서드에 두 번 적용합니다. 첫 번째 사용은 매월 말일을 지정하고 두 번째 사용은 금요일 오후 11시를 지정합니다. 다음 코드 예시와 같이 작성합니다:

@Schedule(dayOfMonth = "last")
@Schedule(dayOfWeek = "Fri", hour = 23)
public void doPeriodicCleanup() {
    // 메서드 내용
}