✏️ Info.
Java 애노테이션 학습
📋 List.
1. 애노테이션 정의하는 방법
2. 내장 애노테이션(Built In Annotation)
3. @retention
4. 리플렉션 reflection 사용
5. @target
6. @documented
7. 애노테이션 프로세서
✔️ Content.
1. 애노테이션 정의하는 방법
1). 애노테이션
- Java 애노테이션은 자바 소스코드에 추가하여 사용할 수 있는 메타데이터의 일종
- 메타데이터 : 컴파일/런타임 과정에서 코드를 어떻게 컴파일하고 처리할 것인지 알려주는 정보
- 보통 @기호를 앞에 붙여서 사용한다.
- Java 1.5 이상에서 사용 가능
- 애노테이션은 클래스 파일에 임베디드 되어 컴파일러에 의해 생성된 후 자바 가상머신에 포함되어 작동한다.
용도
- 컴파일러에게 코드 문법 에러를 체크하도록 정보 제공
- ex) @Override
- 소프트웨어 개발 툴이 빌드나 배치 시 코드를 자동으로 생성할 수 있도록 정보 제공
- 애노테이션은 빌드 시 자동으로 XML 설정 파일을 생성하거나, 배포를 위해 JAR 압축 파일을 생성하는 데에도 사용된다.
- 런타임 시 특정 기능을 실행하도록 정보 제공
정의
- 인터페이스를 정의 하는것과 유사하다.
public @interface customAnnotation {
}
- 클래스의 필드처럼 엘리먼트라 하는 멤버를 가질 수 있다.
- 각 엘리먼트는 타입과 이름으로 구성되며, 디폴트 값을 가질 수 있다.
- 앨리먼트 타입으로는 primitive type, String, Enum, Class Type, 이들의 배열 타입을 사용 가능하다
- 디폴트 값이 없는 값은 반드시 값을 명시해야 한다. 디폴드 값이 있는 값은 생략이 가능하다.
// Annotation
public @interface customAnnotation {
String name();
int age() default 0;
color COLOR_ENUM() default color.RED;
}
// 사용 예
@customAnnotation(name = "custom")
public class annotationExecute {
}
2. 내장 애노테이션(Built In Annotation)
애노테이션 | 설명 | 위치 |
@Override | 부모의 메서드를 오버라이드한 것임을 컴파일러에게 알려주는 역할 | java.lang |
@Deprecated | 사용 하지 않는걸 권장하는 대상임을 알려준다. | |
@SuppressWarnings | 컴파일러의 특정 경고 메시지가 나타나지 않게 해준다. | |
@SafeVarargs | 제네릭 타입의 가변인자에 사용. (Java 7 부터 추가) |
|
@FunctionalInterface | *함수형 인터페이스임을 알린다. (Java 8 부터 추가) |
|
@Retention | 애노테이션이 유지되는 범위를 지정할 때 사용 (*메타 애너테이션) |
java.lang.annotation |
@Target | 애노테이션이 적용 가능한 대상을 지정할 때 사용 (*메타 애너테이션) |
|
@Documented | 애노테이션 정보가 javadoc으로 작성된 문서에 포함되게 한다. (*메타 애너테이션) |
|
@Inherited | 애노테이션이 자손 클래스에 상속되도록 한다. (*메타 애너테이션) |
|
@Repeatable | 애노테이션을 반복해서 사용할 수 있게 한다. (*메타 애너테이션) |
|
@Native | native 메서드에서 참조되는 상수 앞에 붙인다 (Java 8부터 추가) |
* 메타 애너테이션 : 애너테이션을 정의하는데 사용하는 애너테이션의 애너테이션
* 함수형 인터페이스 : Runnalbe 과같은 run() 하나의 추상 메서드만을 갖고 있는 인터페이스
3. @retention
- 사용 용도에 따라 애노테이션의 유지 범위를 지정해야 할 경우 사용
- 세 가지의 범위가 있다.
- 소스 범위에서 유지
- 컴파일 클래스까지 유지
- 런타임까지 유지
- java.lang.annotation.RetentionPolicy 열거 상수로 정의되어 있다.
RetentionPolicy 열거 상수 | 설명 |
SOURCE | 소스상에서만 애노테이션 정보 유지. 소스 코드를 분석할 때만 의미가 있으며. 컴파일된 바이트 코드파일에는 정보가 남지 않음. |
CLASS | 바이트 코드 파일까지 애노테이션 정보를 유지. 하지만 리플렉션을 이용해서 애노테이션 정보를 얻을 수 없다. |
RUNTIME | 바이트 코드 파일까지 애노테이션 정보를 유지. 리플렉션을 이용해서 런타임 시에 애노테이션 정보를 얻을 수 있다. |
* 리플렉션(Reflection)이란 런타임 시에 클래스 메타 정보를 얻는 기능이다. 해당 기능을 사용해 애노테이션 정보를 얻기 위해서는 Retention Level 이 RUNTIME이여야 한다.
4. 리플렉션 reflection 사용
Annotation
// Runtime 범위 까지 사용 가능하게 지정
@Retention(RetentionPolicy.RUNTIME)
public @interface customAnnotation {
String name();
int age() default 0;
color COLOR_ENUM() default color.RED;
}
Class
public class annotationExecute {
@customAnnotation(name = "test1")
public void reflectionTest() {
System.out.println("defalut method()");
}
@customAnnotation(name = "test2", age = 3)
public void reflectionTest2(){
System.out.println("defalut method2()");
}
@customAnnotation(name = "test3", age = 5, COLOR_ENUM = color.BLUE)
public void reflectionTest3(){
System.out.println("defulat method3()");
}
}
사용
void reflectionTest(){
//Annotation 선언된 Class 가져오기
Class<annotationExecute> annotationExecuteClass = annotationExecute.class;
// Class 내부 모든 Method 가져오기
Method[] declaredMethods = annotationExecuteClass.getDeclaredMethods();
//선언된 Annotation 가져오기
Class<customAnnotation> customAnnotationClass = customAnnotation.class;
for (Method declaredMethod : declaredMethods) {
//가져온 Method 중 customAnnotation Annotation 이 선언된 메소드인지 체크
if (declaredMethod.isAnnotationPresent(customAnnotationClass)){
// method 에 선언된 annotation 가져오기
customAnnotation annotation = declaredMethod.getAnnotation(customAnnotationClass);
// method 이름
System.out.print(declaredMethod.getName() + " : \t");
// method 에 선언된 annotation age()
System.out.print("age = " + annotation.age());
// method 에 선언된 annotation name()
System.out.print("\t name = " + annotation.name());
// method 에 선언된 annotation color()
System.out.println("\t color = " + annotation.COLOR_ENUM());
try {
// method 호출
declaredMethod.invoke(new annotationExecute(), null);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
출력
reflectionTest : age = 0 name = test1 color = RED
defalut method()
reflectionTest3 : age = 5 name = test3 color = BLUE
defulat method3()
reflectionTest2 : age = 3 name = test2 color = RED
defalut method2()
5. @target
- 애노테이션 적용 대상을 지정할 때 사용하는 애노테이션
- 적용 대상은 java.lang.annotation.ElementType 열거 상수로 정의되어 있다.
- 기본 앨리먼트 value는 복수개를 지정할 수 있게 ElementType 배열을 값으로 가진다
ElementType 열거 상수 | 적용 대상 |
TYPE | 클래스 , 인터페이스, 열거 타입 |
ANNOTATION_TYPE | 애노테이션 |
FIELD | 필드 |
CONSTRUCTOR | 생성자 |
METHOD | 메소드 |
LOCAL_VARIABLE | 로컬변수 |
PACKAGE | 패키지 |
적용
- 클래스에 적용한 애노테이션을 필드에만 적용이 가능하도록 @Target 지정 시 컴파일 에러 발생
@Target(ElementType.FIELD) // 필드만 사용 가능하게 지정
public @interface customAnnotation {
String name();
int age() default 0;
color COLOR_ENUM() default color.RED;
}
6. @documented
- 애노테이션에 대한 정보가 javadoc으로 작성한 문서에 포함되도록 한다.
- 표준 애노테이션 중 @Override, @SuppressWarnings를 제외하고 모두 @Documented 애노테이션이 붙어 있다.
정의
@Documented
public @interface javaDocAnnotation {
String author();
String date();
int version();
}
사용
@javaDocAnnotation(author = "wony",date = "2021.03.02",version = 1)
public class javadocCreate {
}
1). JavaDoc 생성
- Generate JavaDoc 사용
- JavaDoc scope로 현재 파일 지정(File)
- 한글 입력 시 한글이 깨지지 않게 하기 위해 Other command line arguments에 아래 내용입력
- -encoding UTF-8 -charset UTF-8 -docencoding UTF-8
- 생성 후 Output directory에 index.html을 통해 확인 가능
7. 애노테이션 프로세서
- 일반적으로 애노테이션에 대한 코드 베이스를 검사, 수정 또는 생성하는 데 사용
- Java 컴파일러의 플러그인 일종
- Javac의 일부이므로 모든 처리가 런타임보다는 컴파일 시간에 발생하기 때문에 빠르다.
- 리플렉션을 사용하지 않는다.
- 보일러 플레이트 코드를 생성해준다.
- 대표적으로 lombok
❗️ Refer.
- 애노테이션 정의하는 방법
https://ko.wikipedia.org/wiki/%EC%9E%90%EB%B0%94_%EC%95%A0%EB%84%88%ED%85%8C%EC%9D%B4%EC%85%98
https://webcoding-start.tistory.com/17
- 내장 애노테이션
https://www.notion.so/37d183f38389426d9700453f00253532
- @reterntion
https://webcoding-start.tistory.com/17
- @tartget
https://webcoding-start.tistory.com/17
- @documented
https://b-programmer.tistory.com/264
- 애노테이션 프로세서
https://www.charlezz.com/?p=1167
'Live-Study' 카테고리의 다른 글
[13주차] I/O (0) | 2021.02.19 |
---|---|
[11주차] Enum (0) | 2021.02.19 |
[10주차] 멀티쓰레드 프로그래밍 (0) | 2021.02.19 |
[9주차] 예외 처리 (0) | 2021.02.19 |
[8주차] 인터페이스 (0) | 2021.02.19 |