개발 일지/Java

[Java] 애너테이션(Annotation)

미숫가루설탕많이 2023. 1. 6. 11:10

 애너테이션(annotation)은 주석이랑 비슷한 기능을 하며, 마찬가지로 정보 전달을 위해 만들어진 문법 요소이다.

 

 주석이랑 차이점이 있다면 정보를 전달하는 대상이 다르다는 것이다. 주석은 개발자에게 정보를 전달하는 반면, 애너테이션은 다른 프로그램에게 정보를 전달한다. 즉, 소스 코드가 컴파일되거나 실행될 때 컴파일러 및 다른 프로그램에게 필요한 정보를 전달해 준다.

 

 애너테이션은 @로 시작하고 클래스, 인터페이스, 필드, 메서드 등에 붙여서 사용할 수 있다.

public class ExampleClass implements ExampleInterface {
    @Override
    public void example() {

    }
}

 

 위 코드에서 @Override는 example()이 추상 메서드를 구현하거나 상위 클래스의 메서드를 오버라이딩한 메서드라는 것을 컴파일러에게 알려준다.

 

 애너테이션은 JDK가 기본적으로 제공하는 애너테이션과, 다른 프로그램에서 제공하는 애너테이션이 있다.

 

 JDK에서 기본적으로 제공하는 애너테이션은 표준 애너테이션, 메타 애너테이션 두 가지로 구분된다. 위 코드의 @Override와 같이 다른 문법 요소에 붙여서 사용하는 것은 표준 애너테이션이고, 메타 애너테이션은 애너테이션을 직접 정의해서 사용할 때 사용하는 애너테이션이다.

 

 이처럼 사용자가 애터네이션을 직접 정의해서 사용할 수도 있으며, 이러한 애너테이션을 사용자 정의 애너테이션이라고 한다.

 

 

 

 

표준 애너테이션


 다양한 표준 애너테이션들이 있지만 @Override, @Deprecated, @SuppressWarnings, @FunctionalInterface 네 가지 애너테이션이 가장 빈번하게 사용된다.

 

 

@Override

 대표적인 애너테이션으로 메서드 앞에만 붙일 수 있다.

 

 선언한 메서드가 상위 클래스의 메서드를 오버라이딩하거나 추상 메서드를 구현하는 메서드라는 것을 컴파일러에게 알려준다.

 

 컴파일 과정에서 컴파일러가 @Override를 발견하면 @Override가 붙은 메서드와 동일한 이름을 가진 메서드가 상위 클래스나 인터페이스에 있는지 검사하고 만약 메서드를 찾을 수 없다면 컴파일 에러가 발생한다. 그 이유는 종종 코드를 작성함에 있어서 실수로 메서드의 이름을 잘못 작성하는 경우가 많은데 런타임 에러 시에 에러의 원인을 찾기 힘들기 때문에 이를 방지하기 위해서이다.

 

 

 

 

@Deprecated

 더 이상 사용되지 않는 필드나 메서드에 붙인다.

 

 이는 새로운 기술이 추가되면서 기존에 사용하던 기술을 대체하여 기존 기술을 적용한 코드를 더 이상 사용하지 않도록 유도하는 경우에 사용한다. 즉, 기존의 코드를 다른 코드와의 호환성 문제로 삭제하기 곤란해 남겨두어야 하지만 더 이상 사용을 권장하지 않는 경우에 사용한다.

 

 

 

 

@SuppressWarnings

 컴파일러가 보여주는 경고메시지가 나타나지 않게 억제해 준다.

 

 경우에 따라서 경고가 발생할 것이 예상되면서도 묵인해야 할 때가 있는데, 이 경고를 그대로 둔다면 컴파일을 할 때마다 에러메시지가 나타나기 때문에 이 애너테이션을 사용한다.

 

 @SuppressWarnings()의 괄호 안에 억제하고자 하는 경고메시지를 지정해줄 수 있으며, 아래와 같이 여러 개의 경고를 한 번에 묵인하게 할 수도 있다.

@SuppressWarnings({"deprecation", "finally", "null"})

 

 

 

 

@FunctionalInterface

 함수형 인터페이스를 선언할 때 사용한다. 이 애터네이션을 붙이면 컴파일러가 함수형 인터페이스를 올바르게 선언했는지 확인하고 바르게 선언되지 않은 경우에 에러를 발생시킨다.

 

 이는 실수를 방지할 수 있어서 완성도를 높이는 데 큰 도움이 된다.

 

 참고로, 함수형 인터페이스는 단 하나의 추상 메서드만을 가져야 하는 제약이 있다.

 

 

 

 

메타 애너테이션


 메타 애너테이션은 애너테이션을 위한 애너테이션이다.

 

 애너테이션을 정의하는 데 사용되며, 애너테이션의 적용 대상 및 유지 기간을 정의하는 데 사용된다.

 

 애너테이션을 정의할 때는 @interface 키워드를 사용하여 정의하며 @Target, @Retention 등의 애너테이션을 붙여서 애너테이션의 적용 대상과 유지 기간을 지정한다.

 

 

 

 

@Target

 애너테이션을 적용할 대상을 지정하는 데 사용된다.

 

 @Target 애너테이션을 사용하여 지정할 수 있는 대상 타입으로는 ANNOTATION_TYPE, CONSTRUCTOR, METHOD 등이 있으며, 모두 java.lang.annotation.ElementType 이라는 열거형에 정의되어 있다.

 

 

 

 

@Documented

 애너테이션에 대한 정보가 javadoc으로 작성한 문서에 포함되도록 하는 애너테이션 설정이다.

 

 자바에서 제공하는 표준 애너테이션과 메타 애너테이션 중 @Override와 @SuppressWarning를 제외하고 모두 @Documented가 적용되어 있다.

 

 

 

 

@Inherited

 하위 클래스가 애너테이션을 상속받도록 한다.

 

 @Inherited 애너테이션을 상위 클래스에 붙이면, 하위 클래스도 상위 클래스에 붙은 애너테이션들이 동일하게 적용된다.

 

 

 

 

@Retention

 특정 애너테이션의 지속 시간을 결정하는 데 사용된다.

 

 애너테이션과 관련한 유지 정책의 종류에는 다음의 세 가지가 있다.

 

  • SOURCE
    : 소스 파일에 존재, 클래스 파일에는 존재하지 않음
  • CLASS
    : 클래스 파일에 존재, 실행 시 사용 불가, 기본값

  • RUNTIME
    : 클래스 파일에 존재, 실행 시 사용 가능

 

 

 

 

@Repeatable

 애너테이션을 여러 번 반복해서 쓸 수 있도록 허용한다.

 

 일반적인 애너테이션과 달리 같은 이름의 애너테이션이 여러 번 적용될 수 있기 때문에, 하나로 묶어주는 애너테이션을 별도로 작성해야 한다.

@interface ToDos {  // 여러개의 ToDo 담을 컨테이너 애너테이션 ToDos
    ToDo[] value(); 
}

@Repeatable(ToDos.class) // 컨테이너 애너테이션 지정 
@interface ToDo {
	String value();
}

 

'개발 일지 > Java' 카테고리의 다른 글

[Java] 스트림(Stream)  (0) 2023.01.06
[Java] 람다식(Lambda Expression)  (0) 2023.01.06
[Java] 반복자(Iterator)  (0) 2023.01.04
[Java] Map<K, V>  (1) 2023.01.04
[Java] Set<E>  (0) 2023.01.04