본문 바로가기

Java

어노테이션(Annotation)

어노테이션(Annotation)

어노테이션(Annotation)은 메타데이터(metadata)라고 볼 수 있다. 메타테이터란 컴파일 과정과 실행과정에서 코드를 어떻게 how 컴파일하고 처리할 건지 정보!

어노테이션의 용도

-컴파일러에게 코드 문법 에러를 체크하도록 정보 제공

-개발 툴이나 빌드나 배치 시 코드를 자동으로 생성할 수 있도록 정보 제공

-실행(런타임 시) 특정 기능을 실행하도록 정보 제공

컴파일러에게 코드 문법 에러 체크하도록 정보 제공하는 대표적인 예는 @Override 어노테이션이다.

이거 오버라이드(재정의)된 건데 정확하게 문법 썼는지 체크해라!고 말하는거랑 같다.

그 외에도 @Deprecated(더 이상 안 쓰는 메서드, 쓸 경우 경고!) @SuppressWarnings(컴파일 경고 무시), @FunctionallInterface, @SafeVarargs등이 있음.

java에서 기본적으로 제공하는 것들

이 @어노테이션을 내가 원하는 대로 만들어서 쓸 수 있다.

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

인터페이스와 유사한데 @interface를 사용해서 어노테이션을 정의한다.

public @interface AnnotationName{
}

이렇게 정의한 어노테이션은 @AnnotationName으로 사용한다

@AnnotationName

어노테이션은 엘리먼트(element)를 멤버로 가질 수 있다. 각 엘리먼트는 타입과 이름으로 구성되며, 디폴트 값을 가질 수 있고, 타입도 java에서 쓰는 int나 double, String, 열거, 배열, 클래스 타입 다 쓸 수 있다. 엘리먼트는 외부의 값을 입력받을 수 있는 역할을 한다.

public @interface AnnotationName{
	//타입 elementName() [default 값]; //엘리먼트 선언
	String elementName1();
	int elementName2() default 5;
}

이렇게 정의한 어노테이션을 코드에서 적용할 땐 다음처럼 써야한다.

@AnnotationName(elementName1="하이", elementName2=3);
또는
@AnnotationName(elementName1="하이");

기본 엘리먼트인 value()도 가질 수 있다.

public @interface AnnotationName{
	String value();
	int elementName() default 5;
}

value()로 값을 주면.. 어노테이션에 이름을 적지 않아도 자동으로 값이 할당된다.

@Annotation("안녕");

어노테이션 적용 대상

어노테이션을 적용할 수 있는 대상은 java.lang.annotation.ElementType 열거 상수로 다음과 같이 목록을 가지고 있다.

TYPE → 클래스,인터페이스, 열거 타입

ANNOTATION_TYPE → 어노테이션

FIELD → 필드

CONSTRUCTOR → 생성자

METHOD → 메소드

LOCAL_VARIABLE → 로컬 변수

PACKAGE → 패키지

어노테이션이 적용될 대상을 지정할 땐 @Targer 어노테이션을 사용한다. @Target의 value()는 ElementType 배열을 값으로 가진다. 적용될 대상이 여러 개 일 수 있으니까.

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

}

위에서 타입, 필드, 메소드만 지정해뒀기 때문에 생성자엔 어노테이션 지정할 수 없다.

@AnnotationName
public class ClassName{
	@AnnotationName
	private String fieldName;
	@AnnotationName
	public void methodName(){}
	//@AnnotationName
	public ClassName(){}
}

어노테이션 유지 정책

어노테이션 정의할 땐 어느 범위까지 유지할껀지 정해야 한다.

소스상에서만 유효할건지, 컴파일 된 클래스까지 유효할 건지, 런타임 때도 유효할건지 정해야한다.

java.lang.annotation.RetentionPolicy 열거 상수로 정의되어있다.

-SOURCE : 컴파일 전까지만

-CLASS : 컴파일러가 클래스를 참조할 때까지

-RUNTIME : 컴파일 이후에도 JVM에 의해 계속 참조 가능 (RetentionPolicy.RUNTIME의 경우, 리플렉션을 이용, 런타임시 어노테이션 정보를 얻을 수 있음.

리플렉션이란 런타임 시 클래스의 메타 정보를 얻는 기능을 말한다)

*리플렉션 사용할 때는 java.lang.reflect 패키지의 getFields(), getConstructors(), getDeclaredMethods()등을 사용해서 정보를 얻어올 수 있음..

유지 정책 정할 땐 @Retention사용

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

}

java에서 커스텀 어노테이션 만들고 사용하기 참고

https://elfinlas.github.io/2017/12/14/java-custom-anotation-01/

반응형

'Java' 카테고리의 다른 글

예외 : try-catch-finally  (0) 2021.03.25
예외 : 예외와 예외 클래스  (0) 2021.03.25
static과 싱글톤  (0) 2021.03.11
상속 : 추상 클래스  (0) 2021.03.07
상속 : 타입 변환과 다형성  (0) 2021.03.07