JAVA/자바의 신

17장. 어노테이션이라는 것도 알아야 한다.

hyunsb 2024. 1. 8. 01:04
💡 해당 글은 『자바의 신 3판』을 복습하며 도서의 내용과 본인의 주관적인 생각을 정리한 글입니다.

☁️ 내용정리

어노테이션

어노테이션이란 메타데이터라고 물리기도 하며, @(at) 문자를 통해 표현할 수 있다.

어노테이션은 코드에 부가적인 정보를 제공하는 데 사용되는 표현 방법이다.

어노테이션은 소스코드에 주석 형태로 추가되어 컴파일러, 런타임 환경 또는 다른 프로세스에게 특별한 정보를 전달한다.

대표적인 어노테이션은 다음과 같다.

  • @Override: 해당 어노테이션이 선언되어 있는 메서드는 오버라이드됨을 컴파일러에게 알려줌
  • @Deprecated: 해당 메서드는 더 이상 사용되지 않는다는 것을 컴파일러에게 알려줌 + 경고
  • @Supress Warnings: 경고를 무시한다고 컴파일러에게 알려줌. (사용 시 주석으로 이유를 설명할 것)

 

메타 어노테이션

메타 어노테이션이란 어노테이션을 선언하기 위해 사용하는 어노테이션이다.

  • @Target: 어노테이션이 적용되는 대상을 지정
    • CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE
  • @Retention: 어노테이션의 생명 주기를 선언
    • SOURCE: 어노테이션 정보가 컴파일시 사라짐
    • CLASS: class 파일 까지는 정보가 유지됨, 컴파일러가 참조 가능, VM에서 사라짐
    • RUNTIME: 런타임까지 정보 유지
  • @Document: 해당 어노테이에 대한 정보가 javadocs 문서에 포함됨을 선언
  • @Inherited: 모든 자식 클래스에서 부모 클래스의 어노테이션을 사용가능 함을 선언
  • @Interface: 어노테이션을 선언할 때 사용

 

우리가 자주 마주치는 @Override는 아래와 같이 선언되어 있다.

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

해당 어노테이션은 메서드를 대상으로 지정되며, 어노테이션 정보는 컴파일 시 사라진다.

 

어노테이션 사용하기

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    int number();
    String text() default "This is first annotation";
}
public class UserAnnotationSample {

    @MyAnnotation(number = 0)
    public static void main(String[] args) {
        UserAnnotationSample userAnnotationSample = new UserAnnotationSample();
        userAnnotationSample.checkAnnotation(UserAnnotationSample.class);
    }

    @MyAnnotation(number = 1)
    public void annotationSample1() { }

    @MyAnnotation(number = 2, text = "second")
    public void annotationSample2() { }

    public void checkAnnotation(Class userClass) {
        Method[] methods = userClass.getDeclaredMethods();
        for (Method method : methods) {
            MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
            if (annotation == null) continue;

            System.out.println(annotation.number() + " " + annotation.text());
        }
    }
}

요런 식으로 어노테이션을 설정하고 런타임에 리플렉션을 통해 접근할 수 있다.

0 This is first annotation
1 This is first annotation
2 second

만약 위에서 선언한 MyAnnotationRetentionSOURCE 혹은 CLASS 라면 위의 코드는 아무것도 출력하지 않을 것이다. 리플렉션은 런타임 시 클래스에 접근하기 때문에 생명주기가 컴파일, 바이트코드 까지인 어노테이션은 런타임 시 읽어들일 수 없기 때문이다.

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    int number();
    String text() default "This is first annotation";
}

 


 

☁️ 내 생각

어노테이션은 Spring 프레임워크에서 웹 서버를 개발하며 많이 사용하게 된다.

Spring의 dispatcherServlet도 어노테이션과 리플렉션을 사용하여 구현하고 있다.

Java에서 리플렉션은 java.lang.reflect 패키지에 속한 클래스와 인터페이스를 통해 구현되어 있다.

주요 클래스로는 Class, Method, Field, Constructor 등이 있다. 리플렉션은 런타임에서 현재 실행 클래스의 필드에 접근하거나, 메서드, 어노테이션에 접근할 수 있는 기능을 제공한다.

리플렉션을 사용하면 private로 선언된 필드나 메서드에 접근이 가능해진다. 따라서 보안적인 문제가 발생할 수 있으므로 신중하게 사용해야 한다.

 

 


☁️ 질문

  • 어노테이션이란 무엇인가?
    • 어노테이션이란 컴파일러 혹은 런타임 시 코드에 부가적인 정보를 제공하기 위해 사용되는 표현 방법이다. @(at) 기호를 통해 사용할 수 있으며 생명주기는 컴파일, 바이트코드, 런타임 총 3개로 나누어진다.
  • 어노테이션을 사용하는 예시 하나만 설명해줘라
    • deprecated 어노테이션이 있다. 해당 어노테이션은 더 이상 사용되지 않는 자원을 나타내기 위해 사용된다. 어노테이션이 지원하는 모든 타입에 지정할 수 있고, 생명주기는 런타임 이기 때문에 리플렉션을 통해 접근할 수 있다.
  • 리플렉션이 무엇인가?
    • 리플렉션은 런타임에 실행중인 클래스의 필드, 메서드 등 자원에 접근할 수 있는 기술이다.
  • 리플렉션을 사용할 때의 장단점이 무엇인가?