출처 - Java의 정석 기초편 (남궁 성)
1. 애너테이션이란?
- @태그: 주석처럼 프로그래밍 언어에 영향을 미치지 않고 유용한 정보 제공
- 소스코드 + 소스코드 설명 문서: 주석 /** ~ */ 에 소스 코드에 대한 정보 저장
- javadoc.exe: 소스파일에서 주석 추출해 HTML문서 생성
/** 소스코드 주석
@link // 유용한 정보 제공
@author
@since
*/
소스코드
2. 표준 애너테이션
- 자바에서 기본적으로 제공
@Override
@Deprecated
@SuppressWarnings
@SafeVarargs
@FunvtionalInterface
@Native
@Override
- 컴파일러에게 메서드 오버라이딩하는 것임을 알림
- 오버라이딩 올바르게 했는지 컴파일러가 체크
- 메서드 앞에 @Override 붙이는 습관
class Child extends Parent {
@Override
void parentmethod() {}
}
@Deprecated
- 앞으로 사용하지 않을 것을 권장하는 필드나 메서드
- 컴파일하면 경고 발생
class NewClass {
@Deprecated
int oldField;
@Deprecated
int getOldField() { return oldField; };
}
@FunctionalInterface
- 함수형 인터페이스 올바르게 작성했는지 컴파일러가 체크→잘못된 경우 에러 발생
- 함수형 인터페이스 추상 메서드 하나뿐이어야 함
@FunctionalInterface
public interface Runnable {
public abstract void run(); // 추상 메서드 1개 제약
}
@SuppressWarnings
- 컴파일러의 경고 메시지 억제
- 괄호() 안에 억제하려는 경고 종류를 문자열로 지정
- 둘 이상의 경고를 동시에 억제하려면 괄호{} 사용
@SuppressWarnings("unchecked") // 지네릭스와 관련된 경고 억제
@SuppressWarnings({"deprecation", "unchecked", "varargs"})
3. 메타 애너테이션
- 애너테이션 만들 때 사용
- java.lang.annotation 패키지에 포함
@Target
@Documented
@Inherited
@Retention
@Repeatable
@Target
- 애너테이션 정의시 적용대상 지정
- 여러 개의 값 지정시 괄호{} 사용
import static java.lang.annotation.ElementType.*;
@Target({FIELD, TYPE, TYPE_USE})
public @interface MyAnnotation {} // MyAnnotation 정의
@MyAnnotation // 적용대상 TYPE
class MyClass {
@MyAnnotation // 적용대상 FIELD
int i;
@MyAnnotation // 적용대상이 TYPE_USE
MyClass mc;
}
@Retention
- 애너테이션 유지되는 기간 지정
- 유지 정책(retention policy)
- SOURCE: 소스 파일에만 존재
- CLASS: 클래스 파일에 존재, 실행시 사용불가
- RUNTIME: 클래스 파일에 존재, 실행시 사용가능
// 컴파일러가 사용하는 애너테이션 유지정책(SOURCE)
@Target(ElementType.METHOD)
@Retention(retentionPolicy.SOURCE)
public @interface Override {}
// 실행시 사용 가능한 애너테이션 유지정책(RUNTIME)
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface {}
@Documented, @Inherited
- javadoc으로 작성한 문서에 포함
- 애너테이션을 자손 클래스에 상속
@Inherited
@interface SuperAnno {}
@SuperAnno
class Parent {}
class Child extends Parent {} // Child에 애너테이션 붙은 것으로 인식
@Repeatable
- 반복해서 붙일 수 있는 애너테이션 정의시 사용
- @Repeatable인 @ToDo를 하나로 묶을 컨테이너 애너테이션 추가 정의
@interface ToDos { // 컨테이너 애너테이션 ToDos
ToDo[] value(); // ToDo애너테이션 배열타입의 요소 선언(이름 반드시 value)
}
@Repeatable(ToDos.class)
@interface ToDo {
String value();
}
@ToDo("delete test code.")
@Todo("override inherited methods")
class MyClass {
...
}
4. 애너테이션 타입 정의
- 애너테이션 요소: 추상 메서드 형태(구현 안함)
- 애너테이션 적용시 지정: 순서 상관 없음
- 적용시 값 지정하지 않으면 사용될 수 있는 기본값 지정 가능
- 요소 하나이고 이름이 value인 경우 적용시 이름 생략가능
- 요소 타입이 배열인 경우 괄호{} 사용(값이 하나면 생략 가능, 값이 없으면 반드시 필요)
@interface 애너테이션이름 {
타입 요소이름(); // 애너테이션의 요소 선언
...
}
// 5개 요소 선언
@interface TestInfo {
int count() default 1; // 기본값을 1로 지정
String testedBy();
String[] testTools(); // 배열
TestType testType(); // enum
DateTime testDate(); // 다른 애너테이션
}
@interface DateTime {
Stirng yymmdd();
String hhmmss();
}
// 요소의 값 지정(순서 상관 없음)
@TestInfo ( // count=1
testedBy="KIM",
testTools={"Junit", "AutoTester"},
testType=TestType.FIRST,
testDate=@DateTime(yymmdd="22.11.07", hhmmss="173959")
)
public class NewClass {...}
// 사용
anno.count() // 3
5. 모든 애너테이션 조상
- Annotation: 모든 애너테이션의 조상이지만 상속 불가
- 자신은 인터페이스→equals(), hashCode(), toString() 추상메서드 구현 없이, 모든 애너테이션 객체에 호출 가능
@interface TestInfo extends Annotation // 에러. 상속 불가
6. 마커 애너테이션
- 요소가 하나도 정의되지 않은 애너테이션
- Override, Test, Deprecated 등
@Target(elementtype.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Test {} // 정의된 요소가 없음
7. 애너테이션 요소 규칙
- 요소 타입은 기본형, String, enum, 애너테이션, Class(설계도 객체)만 허용
- 매개변수 선언 불가
- 예외 선언 불가
- 요소 타입에 타입 매개변수<T> 사용 불가
'Java' 카테고리의 다른 글
쓰레드 메서드 (0) | 2022.11.19 |
---|---|
쓰레드(thread) (0) | 2022.11.17 |
열거형(enum) (0) | 2022.11.04 |
지네릭스(Generics) (0) | 2022.11.04 |
HashMap, TreeMap, Collections (0) | 2022.10.30 |