4 분 소요

첫 번째 과제

[인프런 워밍업 클럽 1기] BE 1일차 과제

[질문]

Q. 어노테이션을 사용하는 이유 (효과) 는 무엇일까?

 A. 어노테이션을 사용하는 이유에 대해 아래 내용에서 어노테이션의 정의, 특징, 역할, 장,단점에 대해 자료를 찾아 정리해보면서 나름대로 다음과 같은 결과를 도출 했다.

어노테이션을 사용하면 코드와 설정을 같은 위치에 배치하여 코드의 가독성을 향상시킨다.

클래스, 메서드, 필드, 파라미터 등과 관련된 정보가 함께 있어 코드를 읽고 이해하기 쉬워지며 특히, 코드의 흐름을 파악하기 쉬워진다.

별도의 설정 파일을 작성하지 않고도 어노테이션을 사용하여 설정을 간소화할 수 있다. 이는 개발자가 코드에 직접 설정을 기술할 수 있으므로 설정 관리를 단순화시킨다.

어노테이션을 통해 공통적인 코드 패턴이나 설정을 재사용할 수 있다. 이는 코드의 중복을 줄이고 효율적으로 코드를 작성할 수 있도록 도와준다.

필요한 기능이나 제약 사항을 정의하기 위해 커스텀 어노테이션을 직접 정의할 수 있다. 이것은 프로젝트에서 특정한 요구사항에 대응하기 위해 유연하고 효율적인 방식으로 사용할 수 있다.

어노테이션 프로세서를 사용하면 컴파일 시점에 어노테이션을 처리하고 검증할 수 있다. 또한, 코드를 자동으로 생성하거나 수정할 수 있어서 프로젝트에 필요한 기능을 효과적으로 구현할 수 있다.

어노테이션의 정의

자바에서 어노테이션(Annotation)이란 소스 코드에 메타데이터를 추가하는 방법을 제공하는 기능이다.

어노테이션의 특징

  • 어노테이션은 컴파일러나 런타임 환경에게 정보를 전달할 수 있으며 전달된 정보는 코드를 실행하거나 컴파일할 때 사용된다.

  • 어노테이션은 @ 기호로 시작하며, 주석과 유사하게 생겼지만, 주석과는 달리 컴파일러가 읽고 처리할 수 있다.

  • 정의된 어노테이션은 해당 타겟에 대한 동작을 수행하는 프로그램 외에는 다른 프로그램에게 영향을 주지 않는다.

어노테이션의 역할

  • 컴파일러에게 문법 에러를 체크하도록 정보를 제공한다.

  • 프로그램을 빌드할 때 코드를 자동으로 생성할 수 있도록 정보를 제공한다.

  • 런타임에 특정 기능을 실행하도록 정보를 제공한다.

어노테이션 사용의 장점

  • 코드의 가독성 향상

    • 어노테이션은 코드와 설정을 같은 위치에 배치하므로 읽고 이해하기 쉽다. 클래스, 메서드, 필드, 파라미터 등 연관된 코드와 가까이 있기 때문에 흐름을 따라가기 쉽다.
  • 설정의 간소화

    • 별도의 설정 파일 작성 없이 어노테이션 적용을 통해 설정을 간소화할 수 있다.
  • 중복 코드 제거

  • 공통적인 코드 패턴이나 설정을 재사용할 수 있기 때문에 코드의 중복을 줄이고 효율적으로 코드를 작성할 수 있다.

  • 커스텀 어노테이션 정의

    • 직접 커스텀 어노테이션을 정의함으로 필요한 기능이나 제약 사항을 정의하여 사용할 수 있다.
  • 프로세서를 통한 검증 및 코드 생성

    • 어노테이션 프로세서를 이용해 컴파일 시점에 어노테이션을 처리하고 검증할 수 있다. 또한 코드를 자동으로 생성하거나 수정할 수 있기에 효과적으로 기능을 구현할 수 있다.

어노테이션 사용의 단점

  • 런타임 오버헤드

    • 런타임 시점에 리플렉션을 사용하여 처리하는 어노테이션의 경우 성능상의 오버헤드가 발생할 수 있다.
  • 컴파일 시점 제한

    • 어노테이션도 컴파일 시점에 오류를 확인할 수 있지만, 어노테이션 로직이 런타임에 에러를 발생시키거나 어노테이션에 잘못된 값이 할당된 경우 컴파일 시점에 오류를 확인할 수 없을 수도 있다.

 

어노테이션의 종류

어노테이션은 크게 세 가지로 구분된다. 자바에서 기본적으로 제공하는 빌트인 어노테이션과 어노테이션을 정의하는 데 사용되는 메타 어노테이션, 마지막으로 사용자 어노테이션이 있다.

빌트인 어노테이션

자바에서 기본적으로 제공하는 어노테이션이다.

@Override : 컴파일러에게 메서드를 오버라이딩하는 것이라고 알린다.

@Deprecated : 앞으로 사용하지 않을 대상임을 알린다.

@FunctionalInterface : 함수형 인터페이스라는 것을 알린다.

@SuppressWarning : 컴파일러가 경고 메시지를 나타내지 않는다.

@SafeVaragrs : 제네릭과 같은 가변 인자의 매개변수를 사용할 때의 경고를 나타내지 않는다.

메타 어노테이션

어노테이션에 붙이는 어노테이션으로, 어노테이션을 정의하는 데 사용한다.

@Target : 어노테이션을 정의할 때 적용 대상을 지정하는 데 사용한다.

@Documented : 어노테이션 정보를 javadoc으로 작성된 문서에 포함시킨다.

@Inherited : 어노테이션이 하위 클래스에 상속되도록 한다.

@Retention : 어노테이션이 유지되는 기간을 정하기 위해 사용한다.

@Repeatable : 어노테이션을 반복해서 적용할 수 있도록 한다.

사용자 정의 어노테이션

사용자가 직접 정의하여 사용하는 어노테이션이다.

Q. 나만의 어노테이션은 어떻게 만들 수 있을까?

A. 사용자가 직접 여러 어노테이션을 혼합하거나 정의하여 어노테이션을 만들 수 있다.

기본적으로 인터페이스를 정의하는 것과 유사하며 @interface 뒤에 사용할 어노테이션의 이름을 정의하고 속성을 설정한다.

어노테이션을 정의할 때 기본적으로 포함되야할 메타 어노테이션이 존재한다.

  • @Retention - 어노테이션이 유지되는 기간을 정해야 하며 다음과 같은 열거 상수 중 선택한다.

    • SOURCE : 컴파일할 때 적용 ~ 컴파일된 후에 제거됨

    • CLASS : 메모리로 로딩할 때 적용 ~ 메모리로 로딩된 후에 제거됨

    • RUNTIME : 실행할 때 적용 ~ 계속 유지됨

  • @Target - 어노테이션을 정의할 때 적용 대상을 지정해야 하며 다음과 같은 열거 상수 중 선택한다.

    • TYPE : 클래스, 인터페이스 열거타입

    • ANOTATION_TYPE : 어노테이션

    • FIELD : 필드

    • CONSTERUCTOR : 생성자

    • METHOD : 메서드

    • LOCAL_VARIABLE : 로컬 변수

    • PACKAGE : 패키지

이제 예를 들어 @MyAnnotion이라는 String 속성을 가진 어노테이션을 정의해보겠다.

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

// 사용자 정의 어노테이션 선언
@Retention(RetentionPolicy.RUNTIME) // 어노테이션 정보를 유지할 시점 (런타임까지 유지)
@Target(ElementType.METHOD) // 어노테이션이 적용될 대상 (메서드에 적용)
public @interface MyAnnotation {
    String value() default "test"; // 어노테이션의 속성, 기본값은 빈 문자열

    // 추가적인 속성이 필요하다면 여기에 선언할 수 있습니다.
}

정의한 어노테이션에 사용한 메타 어노테이션은 다음과 같다.

@Retention(RetentionPolicy.RUNTIME): 어노테이션 정보를 런타임까지 유지한다는 것을 의미하며 이렇게 하면 실행 중에 리플렉션(reflection)을 사용하여 어노테이션 정보를 읽을 수 있다.

@Target(ElementType.METHOD): 이 어노테이션은 메서드에만 적용하도록 설정한다.

이제 메인 코드에서 어노테이션을 사용하고 리플렉션을 통해 어노테이션의 정보를 출력해보자.

public class Main {
    @MyAnnotation
    public void myMethod() {
        System.out.println("This is myMethod");
    }

    public static void main(String[] args) throws Exception {
        Main example = new Main();
        example.myMethod();

        // 리플렉션을 이용하여 어노테이션 정보 출력
        java.lang.reflect.Method method = Main.class.getMethod("myMethod");
        MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
        System.out.println("Method name: " + method.getName());
        System.out.println("Annotation value: " + annotation.value());
    }
}

어노테이션의 이름과 속성 값을 출력하는걸 확인할 수 있다.

"C:\Program Files\Java\jdk-11.0.16.1\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2021.1.1\lib\idea_rt.jar=6433:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2021.1.1\bin" -Dfile.encoding=UTF-8 -classpath C:\Users\User\Desktop\test\out\production\test Main
This is myMethod
Method name: myMethod
Annotation value: test

Process finished with exit code 0

참고 자료

[Spring] 스프링을 어노테이션 기반으로 만든 이유 (tistory.com)

[Java] Custom Annotation(커스텀 어노테이션) 만들기 - MangKyu’s Diary (tistory.com)

 

댓글남기기