애노테이션을 정의하는데 사용하는 애노테이션을 메타 애노테이션이라고 한다.
애노테이션의 생존 기간을 정의한다.
애노테이션을 어디에 적용할 수 있는지를 지정한다.
적용 가능한 대상 목록:
애노테이션을 JavaDoc 문서에 포함할지를 결정한다.
기본적으로 애노테이션은 JavaDoc에서 보이지 않는다. 이 애노테이션을 붙이면 JavaDoc에서 노출된다.
부모 클래스의 애노테이션을 자식 클래스에서 자동으로 상속하도록 한다.
기본적으로 애노테이션은 상속되지 않는다.
같은 애너테이션을 중복해서 사용 가능하다.
Java8 이상 부터 사용가능하다.
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Repeatable(MyAnnotations.class) // 같은 애노테이션을 여러 개 적용할 수 있도록 설정
@interface MyAnnotation {
String value();
}
// 여러 개의 MyAnnotation을 감싸는 컨테이너 애노테이션 필요
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface MyAnnotations {
MyAnnotation[] value();
}
// 사용 예시
class Example {
@MyAnnotation("A")
@MyAnnotation("B")
public void myMethod() {}
}
Java에서는 기본적으로 애노테이션은 상속되지 않는다. 하지만 @Inherited 메타 애노테이션을 사용하면, 클래스에서만 애노테이션이 상속될 수 있다.
@Inherited를 붙이면 부모 클래스에 선언된 애노테이션이 자식 클래스에서도 자동으로 적용된다.
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface MyAnnotation {
}
@MyAnnotation
class Parent {}
class Child extends Parent {}
public class Test {
public static void main(String[] args) {
System.out.println(Child.class.isAnnotationPresent(MyAnnotation.class)); // true
}
}
@Inherited는 클래스 계층 구조에서만 동작하며, 인터페이스에는 적용되지 않는다.
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface MyAnnotation {}
@MyAnnotation
interface MyInterface {}
class MyClass implements MyInterface {}
public class Test {
public static void main(String[] args) {
System.out.println(MyClass.class.isAnnotationPresent(MyAnnotation.class)); // false
}
}
그 이유는?