Java

Java_어노테이션(Annotation)

ssmm95 2024. 10. 16. 12:51

Java 코드에서 @으로 작성되는 요소를 어노테이션(Annotation) 이라고 한다

코드에 추가적인 정보를 제공하는 메타데이터 역할을 한다

 

어노테이션은 클래스,인터페이스를 컴파일하거나 실행할 때 어떻게 처리해야 할 것인지를 알려주는 설정 정보이다 

1. 컴파일시 사용하는 정보전달 

2. 빌드 툴이 코드를 자동으로 생성 할 때 사용하는 정보 전달

3. 실행 시 특정 기능을 처리할 때 사용하는 정보 전달

@Override 메서드가 상위 클래스 또는 인터페이스의 메서드를 재정의하고 있음을 나타냅니다.
@Deprecated 해당 요소(클래스, 메서드, 필드 등)가 더 이상 사용되지 않음을 나타냅니다. 컴파일러가 경고를 출력합니다.
@SuppressWarnings 특정 컴파일러 경고를 무시하도록 합니다. 예: "unchecked", "deprecation"
@FunctionalInterface 함수형 인터페이스임을 나타내며, 하나의 추상 메서드만 가지도록 제한합니다.
@SafeVarargs 가변인자 메서드에서 타입 안전성을 보장함을 나타냅니다.
@Retention 어노테이션이 유지되는 범위를 설정합니다. (예: SOURCE, CLASS, RUNTIME)
@Target 어노테이션이 적용될 수 있는 대상을 제한합니다. (예: TYPE, METHOD, FIELD, PARAMETER 등)

 

- 어노테이션 타입 정의와 적용

어노테이션도 하나의 타입이므로 어노테이션을 사용하기 위해서는 먼저 정의부터 해야한다 

public @interface AnnotationName { }
// 인터페이스 위테 어노테이션 이름이 온다 
@AnnotationName

// 어노테이션은 속상을 가질 수 있다
// 속성은 타입과 이름으로 구성 , 이름뒤에 () 괄호를 붙인다 
// 속성의 기본값은 default 키워드로 지정할 수 있다 

예) 
public @interface AnnotationName {
	String prop1();
    int prop2() default 1;
   }
   
 // prop1은 기본값이 없기 때무네 반드시 값을 기술해야 한다 
 // prop2는 기본값이 있기 때문에 생략가능
 
 @AnnotationName(prop1= "값");
 @AnnorarionName(prop1= "값", prop2=3);
 
 //어노테이션은 기본 속성인 value를 다음과 같이 가질 수 있다 
 public @interface AnnotationName {
	String value();
    int prop2() default 1;
   }
 
 //value 속성을 가진 어노테이션을 코드에서 사용할 때에는 다음과 같이 값만 기술 할 수 있다
 // 이 값은 속성에 자동대입된다
 @AnnotationName("값");
 
 //value 속성과 다른 속성의 값을 동시에 주고싶다면 value 속성 이름을 반드시 언급한다
 @AnnotationName(value = "값", prop2=3);
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

// 어노테이션이 런타임까지 유지되도록 설정
@Retention(RetentionPolicy.RUNTIME)
// 어노테이션이 메서드에만 적용되도록 제한
@Target(ElementType.METHOD)
public @interface MyAnnotation {
    String name();
    int age() default 30;
    String[] roles() default {"USER"};
}
public class MyService {

    @MyAnnotation(name = "John", age = 25, roles = {"ADMIN", "USER"})
    public void doSomething() {
        // 메서드 내용
    }

    @MyAnnotation(name = "Doe")
    public void anotherMethod() {
        // 기본 age 값 30과 roles {"USER"}가 적용됩니다.
    }
}

어노테이션 적용 대상 (ElementType)

 

ElmentType 적용 요소
TYPE 클래스, 인터페이스, 열거형, 애노테이션에 적용합니다.
FIELD 필드(멤버 변수)에 적용합니다.
METHOD 메서드에 적용합니다.
PARAMETER 메서드 매개변수에 적용합니다.
CONSTRUCTOR 생성자에 적용합니다.
LOCAL_VARIABLE 로컬 변수에 적용합니다.
ANNOTATION_TYPE 어노테이션 타입에 적용합니다.
PACKAGE 패키지 선언에 적용합니다.
TYPE_PARAMETER 제네릭 타입 매개변수에 적용합니다. (Java 8 이상)
TYPE_USE 모든 타입 선언에 적용할 수 있습니다. (예: 변수 선언, 제네릭, 배열, 캐스팅 등 - Java 8 이상)
@Target( { ElementType.Type,ElementType.Field,ElementType.METHOD })
public @interface AnnotationName {

} // 이 어노테이션은 클래스, 필드, 메소드에 적용할 수 있고 생성자는적용할 수 없다

@AnnotationName // TYPE(클래스)에 적용
public class ClassName {
	@AnnotationName // 필드에 적용
    private String fieldName;
    
    //@AnnotationName @Target CONSTRUCTOR(생성자)가 없으므로 생성자에는 적용 못 함
    public ClassName() {}
    
    @AnnotationName // 메소드에 적용
    public void methodName() {}
  }

 

 

- 어노테이션 유지정책 

어노테이션을 정의할 때 한 가지 더 추가해야할 내용은 @AnnotationName을 언제까지 유지할지 지정하는 것이다

어노테이션 유지정책은 RetentionPolicy 열거 상수로 다음과 같이 정의 되어 있다

RetentionPolicy 열거상수 어노테이션 적용 시점 어노테이션 제거 시점
SOURCE 컴파일할 때 적용 컴파일 된 후에 제거됨
CLASS 메모리로 로딩할 때 적용 메모리로 로딩된 후에 제거됨
RUNTIME 실행할 때 적용 계속 유지됨

 

유지정책을 지정할 때 에는 @Retention 어노테이션을 사용한다 @Retention 의 기본속성인 value는 RetentionPolicy 열거상수 값을 가진다 

아래 예시는 실행시에도 어노테이션을 설정 정보를 이용할 수 있도록 유지정책을 RUNTIME으로 지정한 예시다

@Target( { ElementType.TYPE,ElementType.FIELD,ElementType.METHOD } )
@Retention( RetentionPolicy.RUNTIME )
public @interface AnnotationName {}

 

 

- 어노테이션 설정 정보 이용

어노테이션은 아무런 동작을 가지지 않는 설정 정보일 뿐이다 

이러한 설정 정보를 이용해서 어떻게 처리할 것인지는 애플리케이션의 몫이다 

리플렉션을 이용해서 적용대상으로부터 어노테이션의 정보를 다음 메소드를 얻어낼 수 있다 

리턴타입 메소드(매개변수) 설명
boolean isAnnotationPresent(AnnotationName.class) 지정한 어노테이션이 적용되었는지 여부
Annotation getAnnotation(AnnotationName.class) 지정한 어노테이샨이 적용되어 있으면 어노테이션을 리턴하고 그렇지 않다면 null을 리턴
Annotation[] getDeclaredAnnotations() 적용된 모든 어노테이션을 리턴

'Java' 카테고리의 다른 글

Java_멀티 스레드와 멀티 프로세스의 차이  (0) 2024.10.17
Java_제네릭(Generics)  (0) 2024.10.16
Java_리플렉션  (0) 2024.10.16
Java_날짜와 시간 클래스  (0) 2024.10.16
Java_java.base 모듈  (1) 2024.10.15