ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JAVA] 12주차 과제 : 애노테이션
    Java/온라인 자바 스터디 2024. 4. 11. 18:56
    반응형

    목표

    자바의 애노테이션에 대해 학습하세요.

     

    학습할 것 (필수)

    • 애노테이션 정의하는 방법
    • @retention
    • @target
    • @documented
    • 애노테이션 프로세서

     

    애노테이션 정의하는 방법

    • 자바 애노테이션은 코드 사이에 메타데이터를 제공하는 방법으로, 주석보다 더 많은 기능을 합니다. 이는 소스 코드에 추가할 수 있는 특수한 형태의 '주석'이며, 코드에 정보를 제공하거나 컴파일러에게 특정 동작을 수행하도록 지시하는 등의 목적으로 사용됩니다.
    • 애노테이션은 @interface 키워드를 사용하여 정의합니다. @interface는 자바의 키워드 중 하나로, 애노테이션 정의를 생성하는데 사용됩니다.

     

    다음은 기본적인 애노테이션 구문입니다.

    public @interface MyAnnotation {
       // 애노테이션 요소들
    }

    여기서 MyAnnotation은 소스 코드에서 사용되는 애노테이션 이름이며, 이는 일종의 사용자 정의 데이터 타입으로 봤을 때의 이름과 비슷합니다.

    애노테이션은 선택적으로 요소(element)를 가질 수 있습니다. 이 요소들은 메서드처럼 보일지만 실제로는 값을 추출하기 위한 방법만을 제공합니다. 다음과 같이 애노테이션 요소를 정의할 수 있습니다.

    public @interface MyAnnotation {
       String value() default "Hello";
       int count();
    }

    여기서 value()와 count()는 애노테이션 요소를 정의한 부분으로, default 키워드를 사용해 기본값을 지정할 수 있습니다.

    요소를 가지는 애노테이션을 사용할 때는 다음과 같이 값을 전달합니다.

    @MyAnnotation(value = "Hello World", count = 2)
    public class MyClass {
       // ...
    }

    여기서 value="Hello World"와 count=2는 각 애노테이션 요소에 값을 전달한 예시입니다.

     

    @Retention

    • 자바에서 애노테이션을 정의할 때 해당 애노테이션이 어느 시점까지 유지될 것인지를 지정하는 데 @Retention 애노테이션이 사용됩니다.
    • @Retention 애노테이션은 자바의 메타 애노테이션 중 하나로, 메타 애노테이션은 다른 애노테이션에 적용되는 애노테이션을 말합니다.


    @Retention 애노테이션은 세 가지 RetentionPolicy 중 하나를 값으로 가집니다.

    • SOURCE : 이 정책은 해당 애노테이션의 정보가 컴파일 시점에는 제거됨을 의미합니다. 즉 컴파일된 클래스 파일에는 애노테이션 정보가 포함되지 않습니다. 주로 소스 코드 검사나 코드 도구 등을 위한 애노테이션이 이 정책을 사용하곤 합니다.
    • CLASS : 이 정책은 해당 애노테이션의 정보가 컴파일 시점까지 유지되지만, JVM이 클래스를 메모리에 로드할 때는 애노테이션 정보가 버려집니다. 안드로이드의 일부 코드 작업 도구에서 확인될 수 있습니다.
    • RUNTIME : 이 정책은 애노테이션의 정보가 프로그램이 실행되는 시점까지 유지된다는 것을 의미합니다. 이에 따라 런타임에 리플렉션을 통해 애노테이션 정보를 활용할 수 있습니다.

    이렇게 @Retention 애노테이션은 애노테이션의 수명주기를 조절하며, 필요에 따라 애노테이션을 어느 시점까지 유지할 것인지를 결정할 수 있게 합니다.

    import java.lang.annotation.*;
    
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyCustomAnnotation {
        // ...
    }

    위의 예제에서 MyCustomAnnotation 애노테이션은 런타임에도 유지합니다.


    @Target 

    • @Target 애노테이션은 사용자 정의 애노테이션이 적용될 수 있는 요소의 종류를 지정하는 데 사용되는 메타 애노테이션입니다.
    • @Target에는 java.lang.annotation.ElementType의 상수가 사용됩니다. 이 상수는 애노테이션의 적용 대상을 정의합니다. 

    다음과 같은 ElementType 상수들이 있습니다.

    • TYPE: 클래스, 인터페이스 (포함한 애노테이션 타입), 또는 열거형 선언에 적용
    • FIELD: 필드(멤버 변수) 선언에 적용
    • METHOD: 메소드 선언에 적용
    • PARAMETER: 메서드 매개변수 선언에 적용
    • CONSTRUCTOR: 생성자 선언에 적용
    • LOCAL_VARIABLE: 지역 변수 선언에 적용
    • ANNOTATION_TYPE: 애노테이션 타입 선언에 적용
    • PACKAGE: 패키지 선언에 적용


    다음은 @Target 애노테이션의 사용 예시입니다.

    import java.lang.annotation.ElementType;
    import java.lang.annotation.Target;
    
    @Target({ElementType.METHOD, ElementType.FIELD})
    public @interface MyCustomAnnotation {
        // ...
    }

    위의 예제에서 MyCustomAnnotation은 메서드와 멤버 변수에 적용이 가능합니다.

    구체적인 @Target 값이 지정되지 않은 경우, 해당 애노테이션은 자바의 모든 요소에 대상으로 사용될 수 있습니다. 이를 통해, 애노테이션이 적용될 수 있는 요소의 범위를 제한하거나 특정 요소만을 대상으로 애노테이션을 적용할 수 있게 되며, 이는 코드의 가독성과 유지 보수성을 높이는데 도움을 준다.

     

    @Documented

    @Documented 애노테이션은 사용자 정의 애노테이션에 적용되는 메타 애노테이션입니다. 이 애노테이션이 사용되면 해당 애노테이션이 사용된 요소의 API 문서에 애노테이션 정보가 포함됩니다.
    @Documented 애노테이션은 Javadoc과 같은 문서 생성 도구를 사용해 문서를 생성할 때 유용하게 사용됩니다. 이 애노테이션의 존재 여부에 따라, 사용자 정의 애노테이션이 Javadoc에 포함되거나 포함되지 않을 수 있습니다.

    @Documented 애노테이션의 사용 예시입니다.

    import java.lang.annotation.Documented;
    
    @Documented
    public @interface MyCustomAnnotation {
        // ...
    }

    위 예제에서 MyCustomAnnotation은 @Documented 애노테이션이 적용되어 있기 때문에, 이 애노테이션이 붙은 요소에 대한 Javadoc을 생성할 때, MyCustomAnnotation 애노테이션 정보도 포함됩니다.

    만약 @Documented가 없다면, 사용자 정의 애노테이션은 Javadoc에 포함되지 않습니다.

     

    애노테이션 프로세서

    • Java의 애노테이션 프로세서는 컴파일 시점에 애노테이션을 검사하고 해당 애노테이션에 대한 코드를 생성하거나 실행하는데 사용됩니다. 이를 통해 코드 검사, 코드 생성, 컴파일 시점의 검증 등 다양한 작업을 수행할 수 있습니다.
    • 애노테이션 프로세서는 자바 컴파일러의 플러그인처럼 동작하며 javax.annotation.processing.Processor 인터페이스를 구현하거나 javax.annotation.processing.AbstractProcessor 클래스를 확장하는 클래스를 작성함으로써 정의할 수 있습니다.

    애노테이션 프로세서 작성을 위한 기본적인 단계는 다음과 같습니다.

    1. 애노테이션 프로세서 클래스를 생성합니다. 이 클래스는 javax.annotation.processing.AbstractProcessor 클래스를 확장해야 합니다. 
      • public class MyAnnotationProcessor extends AbstractProcessor {
            @Override
            public boolean process(Set<? extends TypeElement> annotations, 
                                   RoundEnvironment roundEnv) {
              // 처리 로직 작성
              return false;
            }
        }
    2. process() 메서드를 재정의하여 애노테이션 처리 로직을 구현합니다.
    3. javax.annotation.processing.Processor 서비스를 제공하는 파일을 META-INF/services 디렉토리에 생성합니다. 이 파일의 이름은 javax.annotation.processing.Processor이며, 내용은 애노테이션 프로세서 클래스의 완전한 이름이어야 합니다.

    애노테이션 프로세서는 컴파일 시점에 애노테이션을 처리하여 코드를 생성하거나 변경하는 강력한 도구입니다. 이는 Lombok, Dagger, Room Database 등 여러 모던 프레임워크에서 활용되는 중요한 개념입니다.

     

    참조 : https://github.com/whiteship/live-study/issues/12

    반응형

    댓글

Designed by Tistory.