Java : Annotation

공부의 기록·2021년 11월 1일
0

Java

목록 보기
12/19
post-thumbnail

Annotation

본 글은 2021년 12월 19일 에 기록되었다.

이미 @Override 나 @Overload 등의 라는 키워드는 꽤나 낯익은 녀석들이다. 하지만 이 녀석들이 어떠한 기능을 하고 또 Annotation 들이 어떠한 것들이 있는지에 대해서 알아보기 위해서 따로 공부를 진행하게 되었다.


이론

배경

Java 를 개발한 사람들은 소스코드에 대한 문서를 따로 만들기보다 소스코드와 문서를 하나의 파일로 관리하는 것이 낫다고 생각했다. 소스코드의 주석으로부터 HTML 문서를 생성해내는 프로그램 (javadox.exe) 를 만들어서 사용했다.

정의

Annoatation 은 어떠한 대상에 대한 정보를 담고 그에 따라 추가적인 속성 및 기능을 부여해주는 것이라고 생각하면 편하다.

예를 들면,
A 클래스를 상속 중인 B 클래스의 필드 안에서 특정 메서드를 오버라이드 하려고 한다고 해보자.

이 때,
B 클래스의 메서드의 이름이 A 클래스의 이름과 대소문자가 다를 경우, java 에서는 새로운 메서드를 만든 것으로 간주한다.

하지만,
@Override 라는 Annotation 을 붙이면 이를 찾아내고 이름을 변경하라는 메세지를 받을 수 있다.


종류

Annotation 은 크게 다음과 같이 분류가 가능하다.

  1. Meta Annotation
  2. Non-Meta Annotation

이 중 2번 부터 알아보도록 하겠다.

Non-Meta Annotation

@Override
메서드 앞에만 붙일 수 있는 Annotation 으로
조상의 메서드를 오버라이딩 하는 것이라는 걸 컴파일러에게 알린다.

@Deprecated
새로운 버전의 JDK 가 출시될 때,
새로운 기능이 추가되고 이전의 기능이 개선되기도 한다.
이 경우 기존의 기능을 제거할 경우, 이를 사용하고 있는 많은 부분에서 문제가 발생할 수 있다.

따라서 이런 경우에 @Deprecated 를 통해 사용하지 않을 것을 권고한다는 메세지를 남기는 것이다.

@FunctionalInterface
함수형 인터페이스를 선언할 때, 이 Annotation 을 붙이면 컴파일러가 함수형 인터페이스를 올바르게 선언하였는지 확인해준다.

예를 들면,
함수형 인터페이스는 추상 메서드가 하나만 있어야 한다는 제약을 가지는데 이를 준수하였는지를 보는 것이다.

@SuppressWarnings

이는 컴파일러가 보여주는 경고메세지를 억제하도록 하는 Annotation 이다. 물론 이를 남발하여 경고문을 없애라는 목적이 아니다. 이에 대해서는 Effective Java 4 | Generics 중 아이템 27 | 비검사 경고문을 제거하라를 참고하자.

Essesnsial of Java 에서는 가장 많이 쓰이는 것들 로는 다음과 같은 것들이 있다고 적혀있었다.

  1. @SuppressWarnings("deprecation") | 사용이 자제되는 부분을 사용했음을 경고
  2. @SuppressWarnings("unchecked") | 지네릭스로 타입을 지정하지 않음을 경고
  3. @SuppressWarnings("rawtypes") | 로 타입 사용 자제
  4. @SuppressWarnings("varargs) | 지네릭 타입의 가변인자 사용 자제

둘 이상의 경고문을 무시하려면 @SuppressWarnings({"deprecation", "unchecked", "varags"}); 등으로 적으면 된다.

@SafeVarargs
T... args 와 같이 지네릭스 타입의 가변인자를 받아야 할 경우가 있다면,

이에 대한 안전성을 확인하고 @SafeVarargs 을 사용하도록 하자.
주의할 점은 이름은 SafeVarags 이지만, 실제로는 지네릭스 타입에 대한 unchecked 경고를 억제한다는 점이다.
따라서 @SuppressWarnings("varargs") 를 추가로 작성해주어야 한다.

그렇다면 왜 @SupressWarnings({"varargs","unchecked"}) 라고 쓰지 않을까?
그 이유는 @SuppressWarnings("unchecked") 는 작성된 부분의 경고문만 제거해주지만 @SafeArgs 는 작성된 부분과 사용된 부분의 unchecked 경고문을 제거해주기 때문이다.

Meta Annotation

Meta Annotation 은 Annotation for Annotation 이다.
즉, Annotation 의 적용대상이나 적용기간을 정의한다.

이 부분은 아직은 그리고 앞으로도 필요할지에 대한 확신이 없다.
따라서 책을 읽고 리스트업만하고 넘어가도록 하였다.

@Target

@Target 은 Annotation target 을 정의한다.
이 Annotation 이 가르킬 수 있는 대상은 다음과 같다.

대상 타입의미
ANNOTATION_TPYEAnnotation 어노테이션
CONSTRUCTORConstructor 생성자
FIELDField 필드(멤버변수 혹은 enum 상수)
LOCAL_VARAIBLE지역변수
METHODMethod 메서드
PACKAGEPackage 패키지
PARAMETERParameter 매개변수
TYPEType 타입(클래스, 인터페이스, enum)
TYPE_PARAMETERType Parameter 타입 매개변수(지네릭스, jdk 1.8)
TYPE_USEtype_use 타입이 사용되는 모든 곳 (jdk 1.8)

@Documented
Annotation 에 대한 정보가 javadoc 으로 작성한 문서에 포함되도록 한다.
@Override 와 @SuppressWarnings 를 제외한 모든 전술한 Annotation 에 붙어있다.

@Inherited
Annotation 이 자손 클래스에 상속되도록 한다.

@Repeatable
특정한 Annotation 을 반복사용 가능하게 해준다.
사용 예시는 아래에 있다.

@Repeatable(ToDos.class)
@interface Todo {
   String value();
}

@Native
네이티브 메서드 에 참조되는 상수 필드에 붙이는 Annoation 이다.
이는 JVM 이 설치된 OS 의 메서드를 의미하고 이 메서드는 보통 C 언어로 작성되어 있다.
Java 에서는 메서드의 선언부만 작성하고 구현은 하지 않는데, 그래서 추상 메서드처럼 선언부만 있고 몸통이 없다.

public class Object {
   private static native void registerNatives();
   
   static {
      registerNative();
   }
   
   protected native Object clone() throws CloneNotSupportedException;
   
   public final native Class<?> getClass();
   public final native void notify();
   public final native void notifyAll();
   public final native void wait(long timeout) throws InterruptedException;
   public native int hashCode();
   ...
}

모든 클래스의 조상인 Object 클래스는 대부분 Native 메서드이며
이는 Java 로 정의되어 있지만 실제로 호출되는 것은 OS 의 메서드이고
이러한 연결은 JNI(Java Native Interface) 가 하는데 이는 Java 의 영역이나 Essensial of Java 의 범위를 아득히 벗어나는 것 같다.

관련된 포스트 내용을 구글링해서 포스트해두는 것으로 마무리하였다.
JNI 와 NDK 시리즈 - 드럼치는 한동희 님 블로그


정의

Essesnsial of Java 의 715p 부터 720p 까지는
직접 Annotation 을 만들어보고 Marker Annotation 에 대한 내용이 담겨있다.
하지만 Meta Annotation 부터 정의부분까지는 개념적으로도 실제로도 필요한 부분인가에 대한 필요성을 느끼지 못하는 바로 페이지만 적어두고 마무리하였다.

profile
2022년 12월 9일 부터 노션 페이지에서 작성을 이어가고 있습니다.

0개의 댓글