Posts Java-Annotation
Post
Cancel

Java-Annotation

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}

Github Link

This post is licensed under CC BY 4.0 by the author.

Contents

Trending Tags