Effective Java : 아이템27. 완벽공략 - 어노테이션
- 프로그래밍 언어/JAVA
- 2023. 4. 16.
들어가기 전
이 글은 인프런 백기선님의 강의를 복습하며 작성한 글입니다.
이 글의 요약
- 어노테이션은 @Retention을 통해서 어노테이션의 참조 시점을 결정할 수 있다.
- Runtime : JVM 메모리에 올라감 → 런타임 참조 가능
- Class : 바이트 코드까지만 참조 가능. Class 파일에만 선언되어있음.
- Source : 컴파일러가 컴파일 할 때만 참조 가능
- @Target 어노테이션을 이용해 어노테이션의 사용 위치를 설정할 수 있음.
완벽 공략 41. 어노테이션
자바 어노테이션을 정의하는 방법
- @Retention: 어노테이션의 정보를 얼마나 오래 유지할 것인가
- Runtime, Source, Class이 존재함.
- @Target : 어노테이션을 사용할 수 있는 위치
- Type, Field, Method, Parameter, ... 등이 존재함.
이 글에서는 어노테이션을 정의하는 방법과 쓰임새등을 살펴보고자 한다.
@Documented 어노테이션
@Documented 어노테이션이 어노테이션에 선언되어 있으면, 어노테이션을 사용하는 클래스가 Java Doc으로 만들어질 때, 어노테이션 정보가 Java Doc에 포함된다. 아래의 경우 MyClass의 Java Doc에는 @MyAnnotation 정보가 포함된다.
// 이 어노테이션을 사용하는 클래스에서 Java Doc 생성 시
// 어노테이션 정보가 Java Doc에 포함됨.
@Documented
public @interface MyAnnotation {
}
@MyAnnotation
public class MyClass {
}
@Retention 어노테이션
어노테이션에 붙이는 어노테이션이다. @Retention 어노테이션은 어노테이션의 정보를 어느 시점까지 참고할 수 있을지를 결정한다. 아래 세 가지 형태가 있다.
- Runtime : JVM 메모리에 어노테이션 정보가 올라감. 클래스에서 런타임에 참조 가능함.
- Class : 바이트 코드에만 표현되어 있음. 클래스 파일 레벨에서는 참조 가능.
- Source : 컴파일 환경에서만 참조 가능.
위와 같이 각 Rentition 타입은 서로 다른 지속 시간을 가진다. 따라서 어떤 목적으로 사용하는지에 따라서 다르게 사용할 수 있을 것이다
Runtime
- 런타임 중에도 어노테이션 정보를 활용할 수 있다. 예를 들어 런타임에서 어떤 어노테이션 정보를 가진 클래스를 불러모아 스프링 빈으로 등록하고 싶다면 Retention을 Runtime으로 한다. 불러와서 리플렉션으로 처리할 수 있다. 예를 들면 @Aspect가 될 수 있겠다.
- 런타임에서는 아래처럼 정보를 불러올 수도 있다.
@MyAnnotation
public class MyClass {
public static void main(String[] args) {
Arrays.stream(MyClass.class.getAnnotations()).forEach(System.out::println);
}
}
Class
- 바이트 코드 단계에서 특정 어노테이션을 가진 녀석들을 스프링 빈으로 등록하고 싶다면, Retention 타입을 Class로 사용하면 된다.
- 바이트 코드에서만 어노테이션 정보가 남아있고, 실제 JVM 메모리에는 올라가지 않기 때문에 참조할 수 없다.
Source
- 컴파일러가 자바 코드를 컴파일해서 바이트 코드로 변환하는 과정에서만 참조할 수 있다. 일종의 소스코드의 이해를 돕기 위한 주석 같은 어노테이션이라면 Source로 선언할 수 있다.
- 컴파일러가 컴파일 경고를 만들 때 사용하는 용도라면 Source로 사용할 수 있다. 예시로는 @SuppressWarnings가 있다.
@Target 어노테이션
@Target 어노테이션은 생성된 어노테이션이 어디에 사용될 수 있을지를 결정하는 어노테이션이다. 가장 자주 사용되는 타입은 "Type"인데, 어노테이션이 클래스/인터페이스에서 사용될 수 있도록 한다. 만약 "Type"으로만 되어있으면 메서드에서는 어노테이션을 사용할 수 없다.
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.FIELD})
public @interface MyAnnotation {
}
'프로그래밍 언어 > JAVA' 카테고리의 다른 글
Effective Java : 아이템31. 한정적 와일드카드를 사용해 API 유연성을 높여라 (0) | 2023.04.18 |
---|---|
Effective Java : 아이템28. 배열보다는 리스트를 사용하라 (0) | 2023.04.16 |
Effective Java : 아이템27. 비검사 경고를 제거하라 (0) | 2023.04.16 |
Effective Java : 아이템26. 완벽공략 (GenericRepository) (0) | 2023.04.16 |
Effective Java : 아이템26. 로 타입은 사용하지 마라 (제네릭) (0) | 2023.04.15 |