Annotation
특징
- 사전적 정의 : 주석
- JVM, 컴파일러, 프레임워크 등에서 사용할 수 있도록 전달하는 메타데이터
@Override
,@Deprecated
,@SuppressWarning
등이 있다.Custom Annotation
을 만들기 위해서 @Target과 @Retention을 설정해야한다.
@Target
- Annotation을 사용할 수 있는 대상을 설정한다.
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, MODULE})
1 2 3 4 5 6 7
TYPE : 클래스, 인터페이스 애노테이션 열거형 FIELD : 필드(멤버 변수), 열거형 상수 METHOD : 메소드 PARAMETER : 메소드의 입력 파라미터 CONSTRUCTOR : 클래스의 생성자 LOCAL_VARIABLE : 로컬 변수 MODULE : 모듈
@Retention
- Annotation 정보를 어디까지 유지할지 정하는 정책
@Retention(RetentionPolicy.SOURCE)
: 컴파일러가 사용하며 .java를 .class로 변환하는 과정에서 사용한다. .class파일에는 포함되지 않는다.@Retention(RetentionPolicy.CLASS)
: .class에 포함되며 JVM까지는 유지되지 않는다.@Retention(RetentionPolicy.RUNTIME)
: JVM까지 유지된다. Reflection API를 통해 사용할 수 있다. 실질적으로 컴파일러는 JAVA상으로 구현하지 않으므로 RUNTIME만 활용할 수 있다.
Anootation의 내부 구성
String[] value()
: Annotation의 속성값이다. 기본 속성값은 value이며 배열의 길이가 1이면 String타입으로 입력할 수 있다.String valueTwo()
: Annotation을 사용하는 것의(Method, Field 등등) 값이다.
Annotation의 활용
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
@Target({FIELD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation{
String[] value(); //Annotation 속성. 기본 속성 이름은 value.
String valueTwo() default "Default String"; // 기본적으로 값을 정할 수 있다.
}
class AnnotationsUsage{
@MyAnnotation("game")
String game = "TicTactoe";
// value는 String[]이므로 value에는 배열로 넣어줘야하지만 길이가 1이면 String만 넣어도 됨
@MyAnnotation(value="server", valueTwo = "localhost")
String serverIP ;
@MyAnnotation(value="server", valueTwo = "0000")
String serverPort ;
@MyAnnotation("game")
String gameMode = "AI vs AI";
@MyAnnotation(value="db", valueTwo = "localhost")
String database;
}
public class Annotation {
public static void main(String[] args) throws IllegalAccessException {
AnnotationsUsage obj = new AnnotationsUsage();
Map<String, Object> gameProp = new HashMap<>();
Map<String, Object> serverProp = new HashMap<>();
Map<String, Object> dbProp = new HashMap<>();
Field[] fields = AnnotationsUsage.class.getDeclaredFields();
for(Field field: fields){
// field에서 Annotation 정보를 가져오는 부분(Reflection API)
MyAnnotation annotation = field.getDeclaredAnnotation(MyAnnotation.class);
if(field.get(obj) == null){
field.set(obj, annotation.valueTwo());
}
if(annotation.value()[0].equals("game")){
gameProp.put(field.getName(), field.get(obj));
}else if(annotation.value()[0].equals("server")){
serverProp.put(field.getName(), field.get(obj));
}else{
dbProp.put(field.getName(), field.get(obj));
}
}
System.out.println(gameProp);
System.out.println(serverProp);
System.out.println(dbProp);
}
}
1
2
3
4
출력값
{game=TicTactoe, gameMode=AI vs AI}
{serverIP=localhost, serverPort=0000}
{database=localhost}