Live-Study

[12주차] 애노테이션

youn12 2021. 2. 19. 16:15
✏️ Info.

Java 애노테이션 학습

📋 List.

1. 애노테이션 정의하는 방법
2. 내장 애노테이션(Built In Annotation)
3. @retention
4. 리플렉션 reflection 사용
5. @target
6. @documented
7. 애노테이션 프로세서


✔️ Content.

 

1. 애노테이션 정의하는 방법

 

1). 애노테이션

  • Java 애노테이션은 자바 소스코드에 추가하여 사용할 수 있는 메타데이터의 일종
    • 메타데이터 : 컴파일/런타임 과정에서 코드를 어떻게 컴파일하고 처리할 것인지 알려주는 정보
  • 보통 @기호를 앞에 붙여서 사용한다.
  • Java 1.5 이상에서 사용 가능
  • 애노테이션은 클래스 파일에 임베디드 되어 컴파일러에 의해 생성된 후 자바 가상머신에 포함되어 작동한다.

용도

  • 컴파일러에게 코드 문법 에러를 체크하도록 정보 제공
    • ex) @Override
  • 소프트웨어 개발 툴이 빌드나 배치 시 코드를 자동으로 생성할 수 있도록 정보 제공
    • 애노테이션은 빌드 시 자동으로 XML 설정 파일을 생성하거나, 배포를 위해 JAR 압축 파일을 생성하는 데에도 사용된다.
  • 런타임 시 특정 기능을 실행하도록 정보 제공

정의

  • 인터페이스를 정의 하는것과 유사하다.
public @interface customAnnotation {
}

 

  • 클래스의 필드처럼 엘리먼트라 하는 멤버를 가질 수 있다.
  • 각 엘리먼트는 타입과 이름으로 구성되며, 디폴트 값을 가질 수 있다.
  • 앨리먼트 타입으로는 primitive type, String, Enum, Class Type, 이들의 배열 타입을 사용 가능하다
  • 디폴트 값이 없는 값은 반드시 값을 명시해야 한다. 디폴드 값이 있는 값은 생략이 가능하다.
// Annotation
public @interface customAnnotation {
    String name();
    int age() default 0;
    color COLOR_ENUM() default color.RED;
}

// 사용 예
@customAnnotation(name = "custom")
public class annotationExecute {
}

 

2. 내장 애노테이션(Built In Annotation)

 

애노테이션 설명 위치
@Override 부모의 메서드를 오버라이드한 것임을 컴파일러에게 알려주는 역할 java.lang
@Deprecated 사용 하지 않는걸 권장하는 대상임을 알려준다.
@SuppressWarnings 컴파일러의 특정 경고 메시지가 나타나지 않게 해준다.
@SafeVarargs 제네릭 타입의 가변인자에 사용.
(Java 7 부터 추가)
@FunctionalInterface *함수형 인터페이스임을 알린다.
(Java 8 부터 추가)
@Retention 애노테이션이 유지되는 범위를 지정할 때 사용
(*메타 애너테이션)
java.lang.annotation
@Target 애노테이션이 적용 가능한 대상을 지정할 때 사용
(*메타 애너테이션)
@Documented 애노테이션 정보가 javadoc으로 작성된 문서에 포함되게 한다.
(*메타 애너테이션)
@Inherited 애노테이션이 자손 클래스에 상속되도록 한다.
(*메타 애너테이션)
@Repeatable 애노테이션을 반복해서 사용할 수 있게 한다.
(*메타 애너테이션)
@Native native 메서드에서 참조되는 상수 앞에 붙인다
(Java 8부터 추가)

* 메타 애너테이션 : 애너테이션을 정의하는데 사용하는 애너테이션의 애너테이션

* 함수형 인터페이스 : Runnalbe 과같은 run() 하나의 추상 메서드만을 갖고 있는 인터페이스

 


 

3. @retention

 

  • 사용 용도에 따라 애노테이션의 유지 범위를 지정해야 할 경우 사용
  • 세 가지의 범위가 있다.
    • 소스 범위에서 유지
    • 컴파일 클래스까지 유지
    • 런타임까지 유지
  • java.lang.annotation.RetentionPolicy 열거 상수로 정의되어 있다.
RetentionPolicy  열거 상수 설명
SOURCE 소스상에서만 애노테이션 정보 유지.
소스 코드를 분석할 때만 의미가 있으며. 컴파일된 바이트 코드파일에는 정보가 남지 않음.
CLASS 바이트 코드 파일까지 애노테이션 정보를 유지.
하지만 리플렉션을 이용해서 애노테이션 정보를 얻을 수 없다.
RUNTIME 바이트 코드 파일까지 애노테이션 정보를 유지.
리플렉션을 이용해서 런타임 시에 애노테이션 정보를 얻을 수 있다.

* 리플렉션(Reflection)이란 런타임 시에 클래스 메타 정보를 얻는 기능이다. 해당 기능을 사용해 애노테이션 정보를 얻기 위해서는 Retention Level 이 RUNTIME이여야 한다.

 


 

4. 리플렉션 reflection 사용

 

Annotation 

// Runtime 범위 까지 사용 가능하게 지정
@Retention(RetentionPolicy.RUNTIME)
public @interface customAnnotation {
    String name();
    int age() default 0;
    color COLOR_ENUM() default color.RED;
}

 

Class

public class annotationExecute {

    @customAnnotation(name = "test1")
    public void reflectionTest() {
        System.out.println("defalut method()");
    }

    @customAnnotation(name = "test2", age = 3)
    public void reflectionTest2(){
        System.out.println("defalut method2()");
    }

    @customAnnotation(name = "test3", age = 5, COLOR_ENUM = color.BLUE)
    public void reflectionTest3(){
        System.out.println("defulat method3()");
    }

}

 

사용

void reflectionTest(){

        //Annotation 선언된 Class 가져오기
        Class<annotationExecute> annotationExecuteClass = annotationExecute.class;
        // Class 내부 모든 Method 가져오기
        Method[] declaredMethods = annotationExecuteClass.getDeclaredMethods();

        //선언된 Annotation 가져오기
        Class<customAnnotation> customAnnotationClass = customAnnotation.class;


        for (Method declaredMethod : declaredMethods) {
            //가져온 Method 중 customAnnotation Annotation 이 선언된 메소드인지 체크
            if (declaredMethod.isAnnotationPresent(customAnnotationClass)){

                // method 에 선언된 annotation 가져오기
                customAnnotation annotation = declaredMethod.getAnnotation(customAnnotationClass);

                // method 이름
                System.out.print(declaredMethod.getName() + " : \t");
                // method 에 선언된 annotation age()
                System.out.print("age = " + annotation.age());
                // method 에 선언된 annotation name()
                System.out.print("\t name = " + annotation.name());
                // method 에 선언된 annotation color()
                System.out.println("\t color = " + annotation.COLOR_ENUM());

                try {
                    // method 호출
                    declaredMethod.invoke(new annotationExecute(), null);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }

    }

 

출력

reflectionTest : 	age = 0	 name = test1	 color = RED
defalut method()
reflectionTest3 : 	age = 5	 name = test3	 color = BLUE
defulat method3()
reflectionTest2 : 	age = 3	 name = test2	 color = RED
defalut method2()

 

5. @target

 

  • 애노테이션 적용 대상을 지정할 때 사용하는 애노테이션
  • 적용 대상은 java.lang.annotation.ElementType 열거 상수로 정의되어 있다.
  • 기본 앨리먼트 value는 복수개를 지정할 수 있게 ElementType 배열을 값으로 가진다
ElementType 열거 상수 적용 대상
TYPE 클래스 , 인터페이스, 열거 타입
ANNOTATION_TYPE 애노테이션
FIELD 필드
CONSTRUCTOR 생성자
METHOD 메소드
LOCAL_VARIABLE 로컬변수
PACKAGE 패키지

적용

  • 클래스에 적용한 애노테이션을 필드에만 적용이 가능하도록 @Target 지정 시 컴파일 에러 발생
@Target(ElementType.FIELD) // 필드만 사용 가능하게 지정
public @interface customAnnotation {
    String name();
    int age() default 0;
    color COLOR_ENUM() default color.RED;
}

컴파일 에러


 

6. @documented

 

  • 애노테이션에 대한 정보가 javadoc으로 작성한 문서에 포함되도록 한다.
  • 표준 애노테이션 중 @Override, @SuppressWarnings를 제외하고 모두 @Documented 애노테이션이 붙어 있다.

 

정의

@Documented
public @interface javaDocAnnotation {
    String author();
    String date();
    int version();

}

 

사용

@javaDocAnnotation(author = "wony",date = "2021.03.02",version = 1)
public class javadocCreate {
}

 

1). JavaDoc 생성

  • Generate JavaDoc 사용
  • JavaDoc scope로 현재 파일 지정(File)
  • 한글 입력 시 한글이 깨지지 않게 하기 위해 Other command line arguments에 아래 내용입력
    • -encoding UTF-8 -charset UTF-8 -docencoding UTF-8


 

  • 생성 후 Output directory에 index.html을 통해 확인 가능

JavaDoc


 

7. 애노테이션 프로세서

 

  • 일반적으로 애노테이션에 대한 코드 베이스를 검사, 수정 또는 생성하는 데 사용
  • Java 컴파일러의 플러그인 일종
  • Javac의 일부이므로 모든 처리가 런타임보다는 컴파일 시간에 발생하기 때문에 빠르다.
  • 리플렉션을 사용하지 않는다.
  • 보일러 플레이트 코드를 생성해준다.
  • 대표적으로 lombok 

❗️ Refer.

- 애노테이션 정의하는 방법
https://ko.wikipedia.org/wiki/%EC%9E%90%EB%B0%94_%EC%95%A0%EB%84%88%ED%85%8C%EC%9D%B4%EC%85%98
https://webcoding-start.tistory.com/17

- 내장 애노테이션
https://www.notion.so/37d183f38389426d9700453f00253532

- @reterntion
https://webcoding-start.tistory.com/17

- @tartget
https://webcoding-start.tistory.com/17

- @documented
https://b-programmer.tistory.com/264

- 애노테이션 프로세서
https://www.charlezz.com/?p=1167

'Live-Study' 카테고리의 다른 글

[13주차] I/O  (0) 2021.02.19
[11주차] Enum  (0) 2021.02.19
[10주차] 멀티쓰레드 프로그래밍  (0) 2021.02.19
[9주차] 예외 처리  (0) 2021.02.19
[8주차] 인터페이스  (0) 2021.02.19