17장 - 어노테이션이라는 것도 알아야 한다
어노테이션
정의
- Annotation
- 클래스나 메서드 등 선언 시 @ 사용
- 메타 데이터(Metadata)라 부르기도 함
쓰임
- 컴파일러에 정보 알려줄 때
- 컴파일 및 설치(deployment) 시 작업 지정할 때
- 실행 시 별도 처리 필요할 때
자바 언어에서 사용하기 위해 정해져있는 어노테이션
@Override
- 해당 메서드가 부모 클래스에 있는 메서드 Override 했다는 걸 명시적 선언
@Deprecated
- 컴파일러에 해당 클래스나 메서드는 더 이상 사용하지 않는다는 걸 알려줌
- 컴파일 결과, 경고만 있음(에러 x) = 컴파일 완료 = 클래스 파일 생성됨
@SuppressWarnings
- 컴파일러에 해당 소스는 일부러 이렇게 코딩한 것이니 경고해줄 필요 없다고 알려줌
메타 어노테이션(Meta annotation)
- 어노테이션 선언할 때 사용
@Target
- 어느테이션을 어떤 것에 적용할지를 선언할 때 사용
요소 타입 | 대상 |
CONSTRUCTOR | 생성자 선언 시 |
FIELD | enum 상수 포함한 필드(field) 값 선언 시 |
LOCAL_VARIABLE | 지역 변수 선언 시 |
METHOD | 메서드 선언 시 |
PACKAGE | 패키지 선언 시 |
PARAMETER | 매개 변수 선언 시 |
TYPE | 클래스, 인터페이스, enum 등 선언 시 |
@Retention
- 얼마나 오래 어노테이션 정보 유지되는지 선언
@Retention(RetentionPolicy.RUNTIME)
대상 | |
SOURCE | 어노테이션 정보가 컴파일 시 사라짐 |
CLASS | 클래스 파일에 있는 어노테이션 정보가 컴파일러에 의해 참조 가능함 But 가상머신(Virtual Machine)에서는 사라짐 |
RUNTIME | 실행 시 어노테이션 정보가 가상 머신에 의해 참조 가능 |
@Documented
- 해당 어노테이션에 대한 정보가 Javadocs(API) 문서에 포함된다는 걸 선언
@Inherited
- 모든 자식 클래스에서 부모 클래스의 어노테이션 사용 가능하다는 걸 선언
@interface
- 어노테이션 선언 시 사용
- 어노테이션 선언 예시
package c.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD) // 1
@Retention(RetentionPolicy.RUNTIME) // 2
public @interface UserAnnotation { // 3
public int number(); // 4
public String text() default "This is first annotation"; // 5
}
@Target: 해당 어노테이션 사용 대상 지정
- 예시 : 메서드에 사용 가능하다 지정됨
@Retention: 어노테이션 유지 정보 지정
- 예시 : 실행 시 이 어노테이션 참조
@interface
- 해당 어노테이션 선언 시 @UserAnnotation으로 어노테이션 사용 가능
- 메서드처럼 어노테이션 안에 선언 시, 이 어노테이션 사용할 때 해당 항목에 대한 타입으로 값 지정 가능
- default 예약어 뒤 값 지정
- default 예약어 사용 시 default 뒤에 있는 값이 이 어노테이션 사용할 때의 기본값 됨 = 값 지정하지 않아도 default 값으로 지정됨
package c.annotation;
public class UserAnnotationSample {
@UserAnnotation(number = 0)
public static void main(String[] args) {
UserAnnotationSample sample = new UserAnnotationSample();
}
@UserAnnotation(number = 1)
public void annotationSample1() {
}
@UserAnnotation(number = 2, text = "second")
public void annotationSample1() {
}
@UserAnnotation(number = 3, text = "third")
public void annotationSample1() {
}
}
- 어노테이션 선언 클래스에 지정한 각 메서드 이름에 해당하는 값을 소괄호 안에 넣어주어야함
- 두 개 이상 어노테이션 선언 시
@Target({ElementType.METHOD, ElementType.TYPE})
- 위와 같이 선언 시 메서드와 클래스에서 해당 어노테이션 사용 가능
- 사용 범위 벗어나 선언 시 컴파일 에러 발생함
- 어노테이션에 선언한 값 확인
package c.annotation;
import java.lang.reflect.Method;
public class UserAnnotationCheck {
public static void main(String[] args) {
UserAnnotationCheck sample = new UserAnnotationCheck();
sample.checkAnnotations(UserAnnotationSample.class);
}
public void checkAnnotations(Class useClass) {
Method[] methods = useClass.getDeclaredMethods();
for(Method tempMethod : methods) {
UserAnnotation annotation = tempMethod.getAnnotation(UserAnnotation.class);
if(annotation != null) {
int number = annotation.number();
String text = annotation.text();
System.out.println(tempMethod.getName() + "() : number=" + number + " text=" + text);
} else {
System.out.println(tempMethod.getName() + "() : annotation is null");
}
}
}
}
//결과
//main() : number=0 text=This is first annotation
//annotationSample1() : nubmer=1 text=This is first annotation
//annotationSample2() : number=2 text=second
//annotationSample3() : number=3 text=third
Class 클래스 | Method 클래스 |
클래스 정보 확인 | 메서드 정보 확인 |
자바의 리플렉션(Reflection)이라는 API에서 제공하는 클래스 |
어노테이션은 상속 불가
- enum 클래스가 상속 불가하듯 어노테이션도 선언 시 미리 만들어놓은 어노테이션 확장 불가
어노테이션 용도에 따른 분류
제약사항 등 선언 | 용도 나타날 때 | 행위 나타낼 때 | 처리 나타낼 때 |
@Deprecated @Override @NotNull |
@Entity @TestCAse @WebService |
@Statefull @Transaction |
@Column @XmlElement |
어노테이션 전 | 어노테이션 후 |
설정을 XML이나 properties라는 파일에 지정 설정 복잡해지고 해당 쓰임에 대해 이해하려면 많은 시간 필요 아직 필요한 부분 존재해 남아있긴 함 |
각 설정이 필요한 위치에 관련 설정 존재 코드에 대한 가독성 높아짐 롬복(lombok)이 다양한 어노테이션 사용 도와줌 |
- 롬복 예시
@Getter
@Setter
private boolean employed = true;
- 어노테이션 변환된 모습 : 컴파일 단계에서 생성되기에 역컴파일하지 않는 이상 직접 확인 불가
'Backend > Java' 카테고리의 다른 글
[자바의 신] 19장 (0) | 2022.07.26 |
---|---|
[자바의 신] 18장 (0) | 2022.07.26 |
[자바의 신] 16장 (0) | 2022.07.25 |
[Java] String ➡ Long 타입으로 형변환 (0) | 2022.03.30 |
[Java] 정수 최대값, 최소값 구하기 (0) | 2022.03.28 |
댓글