평소 어노테이션을 많이 사용하지만 이에 대해 무엇이라고 설명할 수 없는 자신을 가르치기(?) 위해 이 글을 정리한다.
다음 정리할 내용을 사이트와 함께 java의 정석도 참고했다.
출처 : https://www.geeksforgeeks.org/annotations-in-java/
1. 어노테이션이란?
프로그램의 소스코드 안에 다른 프로그램을 위한 정보를 미리 약속된 형식으로 포함시킨 것
- java의 정석 발췌 -
- 어노테이션은 @로 시작한다.
- 어노테이션은 컴파일된 프로그램의 행동을 바꾸지 않는다.
- 어노테이션은 프로그램 elements와 메타데이터를 어울리도록 돕는다. 즉, 인스턴스 변수, 생성자, 메소드, 클래스 등등
- 어노테이션은 한 프로그램이 컴파일러에 의해 다뤄지는 방식을 바꿀 수 있기에 순수한 주석이 아니다.
- 어노테이션은 기본적으로 추가적인 정보를 제공하는데 사용된다. 그래서 xml혹은 자바 마커 인터페이스로 대체가 가능하다.
2. 어노테이션 종류
어노테이션은 표준 어노테이션과 우리가 만든 커스텀 어노테이션으로 나뉠 수 있다.
표준 어노테이션을 기반으로 framework에서 많은 어노테이션을 만들어서 좋은 기능을 제공하는 것이다.
사실 우리가 무언가 annotation을 새로 정의해서 사용할 일은 많지 않다. 그래도 이번 기회에 제대로 이해하고 넘어가려고 한다.
General Purpose Annotations
- Overrice : 컴파일러에게 오버라이딩하는 메서드라는 것을 알림
- Deprecatd : 앞으로 사용하지 않을 것을 권장하는 대상에 붙임
- SurpressWariungs : 컴파일러의 특정 경고메시지가 나타나지 않게 함
- SafeVarargs : 지네릭스 타입의 가변인자에 사용
- FuntionalInterface : 함수형 인터페이스라는 것을 알림
Meta Annotations
- Target : 애너테이션이 적용가능한 대상을 지정하는데 사용
- Documented : 애너테이션 저옵가 javadoc으로 작성된 문서에 포함되게 함
- Inherited : 애너테이션이 자손 클래스에 상속되도록 함
- Retention : 애너테이션이 유지되는 범위를 지정하는데 사용
- Repeatable : 애너테이션을 반복해서 적용할 수 있게 함
3. 메타 애너테이션 분석
@Target, @Retention, @Inherited, @Documented, @Repeatable이 있다.
@Target
애너테이션 이 적용가능한 대상을 지정하는데 사용
//사용 예시
@Target({ElementType.TYPE, ElementType.FIELD})
class TargeTest{
}
@Target으로 지정할 수 있는 애너테이션 적용 대상의 종류는 아래와 같다.
- ANNOTATION_TYPE : 애노테이션
- CONSTRUCTORE : 생성자
- FIELD : 필드
- LOCAL_VARIAVLE : 지역변수
- METHOD : 메소드
- PACKAGE : 패키지
- PARAMETER : 매개변수
- TYPE : 타입. class, interface, enum 에 적용
- TYPE_PARAMETER : 타입 매개변수
- TYPE_USE : 타입이 사용되는 모든 곳
보니까 어디에 사용할 지 원하는 항목만 지정해주면 된다.
@Retention
애너테이션 유지 기간 설정에 사용
//사용 예시
@Retention(RetentionPolicy.RUNTIME)
public class test{
...
}
유지 정책
- SOURCE : 소스 파일에만 존재. 클래스파일에는 존재하지 않음
- CLASS : 클래스 파일에 존재. 실행시에 사용 불가. 기본값
- RUNTIME : 클래스 파일에 존재. 실행시에 사용가능.
SOURCE는 실제로 컴파일러를 작성할 것이 아니면 사용할 일이 없다.
CLASS는 컴파일러가 애너테이션의 정보를 클래스 파일에 저장할 수 있게는 하는데 JVM 로딩시에는 이 정보가 무시되어 애너테이션에 대한 정보를 못 얻는다. 그럴바에는 RUNTIME을 많이 사용한다.
RUNTIME는 실행시 Reflection을 통해 클래스파일에 저장된 애너테이션 정보를 읽어 처리한다.
@Documented
애너테이션 정보가 javacdoc으로 작성된 문서에 포함되도록 한다.
@Inherited
애너테이션이 자손 클래스에 상속되도록 한다.
// 사용 예시
public @interface TestAno1 { }
@TestAno1
class TestParentClass{
static class ChildClass extends TestParentClass{}
}
@Native
네이티브 메서드에 의해 참조되는 상수 필드에 붙이는 애너테이션
4. 커스텀 어노테이션 만들기
애너테이션 요소 선언시 반드시 지켜야 하는 규칙이 있다고 한다.
- 요소의 타입은 기본형, String, enum, 애너테이션, Class만 허용한다.
- ()안에 매개변수를 선언할 수 없다.
- 예외를 선언할 수 없다.
- 요소를 타입 매개변수로 정의할 수 없다.
package realBasic.core.autowired;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface CustomAnnotation { }
@CustomAnnotation
class TestParentClass{
//@CustomAnnotation <= target은 Type(class, interface, enum만 적용 가능.)
String test1;
@CustomAnnotation
static class ChildClass extends TestParentClass{
}
}
Type을 잘 설정해주면 어떤 것이든 애너테이션 적용이 가능하다.
사실 그렇게 어려운 내용들은 아니고 내가 실제로 만들어서 사용할 일은 거의 없다.
그래도 무언가 매일 사용하는데 내부에 의미라고 잘 알고 싶어서 간단히 정리해봤다.
'programming language > Java' 카테고리의 다른 글
List 관련 질문 답변 정리 (3) | 2022.04.04 |
---|---|
static / final / static final이란? (2) | 2022.04.03 |
리플렉션(Reflection)과 jdk 동적 프록시(dynamic proxy) (0) | 2022.03.27 |
제네릭 이해하기 (2) | 2022.03.26 |
interface vs abtract class (4) | 2022.02.06 |