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

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

[인프런 워밍업 클럽 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)

 

댓글을 작성해보세요.