S E P H ' S
[Java] 6. Annotation 본문
Annotation
Annotation의 사전적 의미는 주석이란 뜻입니다. 인터페이스를 기반으로 한 문법이고 주석과는 역할이 다르지만 주석처럼 코드에 달아 클래스에 특별한 의미를 부여하거나 기능을 주입할 수 있습니다. Annotation에는 크게 세 가지 종류가 존재합니다. JDK에 내장되어 있는 built-in-annotation, Annotation에 대한 정보를 나타내기 위한 Meta annotation, 그리고 개발자가 직접 만들어내는 Custom Annotation이 있습니다.
문법으로서 Annotation의 역할
기존의 Java 웹 애플리케이션들은 구성과 설정값들을 외부의 XML 설정 파일에 명시하는 방법으로 프로그래밍 되었습니다. 변경될 수 있는 데이터들을 코드가 아닌 외부 설정 파일에 분리하기 때문에 재컴파일 없이도 쉽게 변경사항을 적용할 수 있었지만, 프로그램 작성을 위해 매번 많은 설정을 작성해야 한다는 불편함이 존재했습니다. 이러한 단점을 해결하기 위해 고안된 문법이 Annotation입니다.
Annotation을 직접 명시함으로써 데이터에 대한 유효조건을 쉽게 파악할 수 있게 되고 코드가 깔끔해집니다. 단순히 부가적 표현 뿐만이 아닌 Reflection 개념을 사용하여 Annotation지정만으로 원하는 클래스를 주입할 수도 있습니다.
이러한 Annotation은 크게 문서화, 컴파일러 체크, 코드 분석을 위한 용도로 사용되고 본질적인 목적은 소스 코드에 메타데이터를 표현하는 것입니다.
Reflection
JVM에서 실행되는 애플리케이션의 런타임 동작을 검사하거나 수정할 수 있는 기능이 필요한 프로그램에서 사용됩니다.
클래스의 구조를 개발자가 확인할 수 있고, 값을 가져오거나 메소드를 호출하는데 사용됩니다.
Built-In Annotation
이미 JDK에 내장되어 있는 Annotation입니다. 주로 컴파일러에게 유용한 정보를 제공합니다.
@Override
메소드 앞에만 붙일 수 있으며, 현재 메소드가 상위 클래스의 메소드를 오버라이드한 메소드임을 컴파일러에게 명시합니다.
오버라이딩 할 때 메소드 명에서 오타가 발생할 수 있는데 컴파일러 입장에서는 이것이 새로운 메소드를 생성하는지, 오버라이딩을 하는 것인지 알 수가 없습니다. 이 경우 Annotation을 통해서 컴파일러에게 오버라이딩을 하는 메소드라는 것을 알려줄 수 있습니다.
@Deprecated
차후 버전에 지원되지 않을 수도 있기 때문에 더 이상 사용되지 말아야 할 메소드를 나타냅니다.
@SupressWarning
프로그래머의 의도를 컴파일러에게 전달하여 경고를 제거합니다.
@FunctionalInterface
컴파일러에게 다음의 인터페이스는 함수형 인터페이스라는 것을 알립니다. @Override 과 같은 이유로 오타와 같은 실수를 방지하기 위해 사용합니다.
Meta-Annotation
Annotation에 사용되는 Annotation입니다. 해당 Annotation의 동작 대상을 결정합니다.
주로 새로운 Annotation을 정의할 때 사용됩니다.
@Target
Annotation이 적용가능한 대상을 지정하는데 사용합니다. 여러 개의 값을 지정할 때는 배열에서처럼 괄호 {}를 사용해야 합니다.
ElementType 열거 상수 | 적용대상 |
TYPE | 클래스, 인터페이스, 열거 타입 |
ANNOTATION_TYPE | 어노테이션 |
FIELD | 필드 |
CONSTRUCTOR | 생성자 |
METHOD | 메소드 |
LOCAL_VARIABLE | 로컬 변수 |
PACKAGE | 패키지 |
@Retention
Annotation이 유지되는 기간을 지정하는데 사용합니다.
세 가지의 유지 정책을 사용할 수 있습니다.
보통 Annotation은 런타임 시에 많이 사용하므로 대부분 Annotation의 Retention값은 RUNTIME으로 되어있습니다.
RetentionPolicy 열거 상수 | 설명 |
SOURCE | 소스상에서만 어노테이션 정보를 유지합니다. 소스 코드를 분석할 때만 의미가 있으며, 바이트 코드 파일에는 정보가 남지 않습니다. |
CLASS | 바이트 코드 파일까지 어노테이션 정보를 유지합니다. 하지만 Reflection을 이용해서 어노테이션 정보를 얻을 수는 없습니다. |
RUNTIME | 바이트 코드 파일까지 어노테이션 정보를 유지하면서 Reflection을 이용하여 런타임에 어노테이션 정보를 얻을 수 있습니다. |
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface() {}
@Inherited
Annotation이 자손 클래스에도 상속되도록 하는 Annotation입니다. 이 Annotation을 조상 클래스에 붙이면 자손 클래스도 이 Annotation이 붙은 거과 같이 인식됩니다.
@Native
네이티브 메소드에 의해 참조되는 상수필드에 붙이는 Annotation입니다. 네이티브 메소드란 JVM이 설치된 OS의 메소드를 말합니다. 보통 네이티브 메소드는 C언어로 작성되어 있어 Java에서는 메소드의 선언부만 정의하고 구현은 하지 않습니다. Object 클래스의 메소드들은 대부분 네이티브 메소드입니다. 네이티브 메소드와 Java에 정의된 메소드를 연결하는 것을 JNI(Java Native Interface)라고 합니다.
Custom Annotation
public @interface MyAnnotation {}
Annotation 타입 선언은 특별한 종류의 인터페이스입니다.
Annotation 타입 선언을 일반적인 인터페이스 선언과 구분하기 위해 예약어 interface앞에 @를 붙입니다.
암묵적으로 java.lang.annotation.Annotation을 확장하기 때문에 extends절을 가질 수 없습니다.
Annotation은 메타데이터 저장을 위해서 클래스처럼 멤버를 가질 수 있습니다. Annotation내에 선언된 메소드를 Annotation의 요소라고 합니다. 이 요소의 개수에 따라 Maker Annotation, Single-Value Annotation, Full Annotation으로 구분할 수 있습니다.
Maker Annotation
요소가 한 개도 없고 단순히 표식으로 사용되는 Annotation입니다. 이 Annotation은 컴파일러에게 의미를 전달하는데 사용됩니다.
Single-Value Annotation
요소로 단일 변수를 갖는 Annotation입니다. 단일 변수밖에 없기 때문에 값만을 명시하여 데이터를 전달할 수 있습니다.
@interface TestInfo {
String value();
}
@TestInfo("passed") // @TestInfo(value="passed") 와 동일합니다
class NewClass{ ... }
Full Annotation
요소로 둘 이상의 변수를 갖는 Annotation으로 데이터를 배열 안에 key-value 형태로 전달합니다.
이 요소에는 규칙이 존재합니다.
1. 요소의 타입은 기본형, String, enum, Annotation, Class만 허용됩니다.
2. 요소의 ()안에 매개변수를 선언할 수 없습니다.
3. 예외를 선언할 수 없습니다.
4. 요소를 타입 매개변수로 정의할 수 없습니다.
'Programing & Coding > JAVA' 카테고리의 다른 글
[Java] 8. final keyword (0) | 2022.01.10 |
---|---|
[Java] 7. Generic (0) | 2022.01.10 |
[Java] 5. Collection (Stack, Queue) (0) | 2022.01.04 |
[Java] 4. Collection (List, Map, Set) (0) | 2021.12.28 |
[Java] 3. 가비지컬렉션(Garbage Collection) (0) | 2021.12.28 |