학습할 것
- 애노테이션 정의하는 방법
- @retention
- @target
- @documented
- 애노테이션 프로세서
Annotations
meta data의 일종, 주석과 비슷한 관계로 미리 약속된 규율이 없었다면 컴파일러는 아무행동도 하지 않는 코드로 생각됩니다.
Annotation은 Java SE 8 부터 활용되고 있으며 활용법은 다음과 같습니다.
- 컴파일러에게 정보를 주는 역할 : 컴파일러가 에러나 경고를 탐지하는데 사용될 수 있음
- 컴파일 시간, 배포 시간처리 : 소프트웨어 툴이 annotation으로 코드를 생성하거나 XML을 생성할 수 있음
- 런타임 처리 : 몇몇 annotation은 런타임 중에 annotation을 검사하고 활용할 수 있습니다.
애노테이션 정의하는 방법
기본형태
@Entity, @{Name}
@ 지시자는 컴파일러에게 이 타입이 Annotation임을 알립니다. 대표적 예시로 @Override를 예시로 들수 있습니다.
또한 annotation은 이름이 지정되거나 지정되지 않은 element를 포함할 수 있으며 각 element들은 값을 가지고 있어야 합니다(not null).
@Author(
name = "Benjamin Franklin",
date = "3/27/2003"
)
class MyClass() { ... }
Annotation을 선언할때 지정할 값이 하나라면 따로 name을 지정해서 value를 설정할 필요가 없습니다. 또한 Annotation은 하나에 선언에 여러개의 Annotation을 선언할 수 있습니다.
같은 Annotation 타입에 여러 값을 선언할때는 Name을 설정해야 합니다.
@SuppressWarnings("unchecked") // → @SuppressWarnings(value = "unchecked") 와 같음
void myMethod() { ... }
//한 선언문에 여러개 선언가능
@Author(name = "Jane Doe")
@EBook
class MyClass { ... }
// 같은 타입에 여러개 값 선언가능 ( java SE8부터 지원)
@Author(name = "Jane Doe")
@Author(name = "John Smith")
class MyClass { ... }
이미 선언되어있는 Annotation
java.lang 과 java.lang.annotation 패키지 안에 이미 선언되어있는 Annotation이 존재합니다.
@Override, @suppressWarings와 같은 Annotation은 이미 Java annotation 패키지 내부에 선언 되어있으며 이 Annotation들은 고유한 타입으로 정의해서 사용할 수 있습니다.
Annotation이 활용되는곳
- Class 인스턴스 생성 표현식
- new @intered MyObject
- Type 변환
- myString = (@Nonnull String) Str;
- implement 절
- clas UnmodifiableList<T> implements
@Readonly List<@Readonly T> { ... }
- clas UnmodifiableList<T> implements
- Thrown된 예외 선언부
- void monitor Temperature() throws
@Critical TemperatureException { ... }
- void monitor Temperature() throws
이런 Annotation을 Type Annotation이라 부르게 됩니다.
Type Annotation
보다 강력하게 데이터의 결함을 방지합니다. 만약 특정 변수가 null이 되는 것을 방지하고 싶을때 @Nonnull String Str; 을 사용하여 str 변수에 null 값이 들어오는 것을 허용하지 않을수 있습니다.
Type Annotation을 사용합으로써 더욱 강력하게 데이터 오류를 방지할 수 있습니다.
Type Annotation 선언방법
Type Annotation을 선언하는 방법은 java의 interface를 선언하는 것과 비슷합니다.
마치 Spring에서 @requestmapping에 value와 method를 설정하는 것과 비슷하다고 생각했습니다.
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;
@Retention(RetentionPolicy.RUNTIME)
@interface AnnotationType{
String userName() default "DY";
}
public class EnumTest {
@AnnotationType
public void take1() throws Exception {
Method method = EnumTest.class.getMethod("take1", null);
AnnotationType annotation = (AnnotationType)method.getAnnotation(AnnotationType.class);
System.out.println(annotation.userName());
}
@AnnotationType(userName = "KIM")
public void take2() throws Exception {
Method method = EnumTest.class.getMethod("take2", null);
AnnotationType annotation = (AnnotationType)method.getAnnotation(AnnotationType.class);
System.out.println(annotation.userName());
}
public static void main(String[] args) throws Exception {
EnumTest test = new EnumTest();
test.take1();
test.take2();
}
}
결과
DY
KIM
이미 정의 되어있는 Annotation Type
- @Deprecated
더 이상 사용하지 않는 요소임을 의미합니다. 만약 이 Annotation이 선언된 요소가 다른곳에서 사용된다면 java 컴파일러는 waring을 생성합니다.
- @Override
매서드를 재정의 하였음을 표기합니다.
- @SuppressWarings
위 @Deprecated가 선언된 매서드나 클래스를 사용할때 컴파일러가 waring을 발생시키는데 이때 @SupperessWarings가 선언되어 있으면 waring이 발생하지 않음
- @SafeVargars
매서드 또는 생성자에 적용될 때 코드가 해당 varargs매게 변수에 대해 잠재적으로 안전하지 않은 작업을 수행하지 않는다는 알림을 발생 - @FunctionallInterface
Java SE 8 이상 버전의 functional 인터페이스의 지시자
@retention
@retention은 해당 Annotation이 어떻게 저장될지 지정합니다.
- RetentionPolicy.SOURCE
표시된 Annotation은 소스레벨에서만 유지되며 컴파일러에서는 무시됩니다. - RetentionPolicy.CLASS
표시된 Annotation은 컴파일 시점에 컴파일러에 의해 유지되지만 JVM에서는 무시 됩니다. - RetentionPolicy.RUNTIME
표시된 Annotation은 JVM에서 유지되므로 런타임 환경에서 사용할 수 있습니다.
@target
Annotation을 사용할 때 종류를 제한하가 위해 사용하는 annotation이라고 합니다
Name | Description |
ElementType.ANNOTATION_TYPE | annotation 타입에 적용 가능 |
ElementType.CONSTRUCTOR | 생성자에 적용가능 |
ElementType.FIELD | 필드, 속성에 적용가능 |
ElementType.LOCAL_VARIABLE | 로컬 변수(지역변수)에 적용가능 |
ElementType.METHOD | 메서드 레벨에서 적용가능 |
ElementType.PACKAGE | 패키지 선언에 적용가능 |
ElementType.PARAMETER | 메서드의 매개변수에 적용가능 |
ElementType.TYPE can be applied to any element of a class. | 클래스 모든 요소에 적용가능 |
@documented
Javadoc tool을 이용해 문서화 해야하는 것을 의미합니다.
javadoc은 우리가 IDE에서 class, interface 혹은 method에 마우스를 올려놨을때 등장하는 팝업을 만들수 있는 도구 입니다.
애노테이션 프로세서
소스레벨에서 컴파일러가 소스를 컴파일 하는 과정에서 활용됩니다.
기존 코드에 새로운 코드를 생성하거나, 변경하는 작업을 가능하게 합니다. 가장 좋은 예시는 Lombok이며
@getter @setter,가 가장 좋은예시 입니다. @getter @setter annotation이 사용되면 자동으로 get, set 메서드를 생성하고 사용할 수 있게 바꿔주지만 소스레벨에서는 메서드 들이 보이지는 않습니다.
컴파일할때 자동 생성됩니다.
reference
- https://docs.oracle.com/javase/tutorial/java/annotations/index.html
'IT 이야기 > Java' 카테고리의 다른 글
[Java Study] 14일차 제네릭(generic) (0) | 2021.02.22 |
---|---|
[Java Study] 13일차 I/O [input/output] (0) | 2021.02.13 |
[Java Study] 11일차 Enum (0) | 2021.01.26 |
[Java Study] 10일차 Thread, Runnable (0) | 2021.01.17 |
[Java Study] 9일차 예외처리(try, catch, throw, throws, finally) (0) | 2021.01.11 |
댓글