元注解
元注解是用于修饰注解定义的注解,控制新注解的行为。
| 元注解 | 作用 | 示例值 |
|---|---|---|
@Target | 限制注解可以应用的位置 | ElementType.METHOD, FIELD, TYPE, PARAMETER 等 |
@Retention | 规定注解保留到哪个阶段 | RetentionPolicy.SOURCE(源码), CLASS(字节码), RUNTIME(运行时反射) |
@Documented | 是否包含在 Javadoc 中 | 默认不包含,加上后注解会出现在文档中 |
@Inherited | 是否允许子类继承父类的注解(仅对类有效) | – |
@Repeatable | 允许同一个位置重复使用同一个注解(Java 8+) | 需要指定容器注解 |
@Target(ElementType[]):
TYPE:类、接口、枚举、注解FIELD:字段(含枚举常量)METHOD:方法PARAMETER:方法参数CONSTRUCTOR:构造器LOCAL_VARIABLE:局部变量ANNOTATION_TYPE:注解类型本身PACKAGE:包TYPE_PARAMETER(Java 8+):类型参数(如class Box<@NotNull T>)TYPE_USE(Java 8+):类型使用处(如new @Interned String())
@Repeatable代码实例:
// 容器注解,用于存储多个重复注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotations {
MyAnnotation[] value();
}
// 可重复注解,并指定容器
@Repeatable(MyAnnotations.class)
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String value();
}
// 使用:多次使用同一个注解
public class RepeatDemo {
@MyAnnotation("first")
@MyAnnotation("second")
public void method() {}
}
自定义注解
@interface 关键字定义注解,可以包含无参数方法作为属性,属性可以通过
default指定默认值
- 基本语法
import java.lang.annotation.*;
@Target(ElementType.METHOD) // 只能用在方法上
@Retention(RetentionPolicy.RUNTIME) // 保留到运行时,可通过反射读取
public @interface MyAnnotation {
// 属性(类似方法)
String value() default ""; // 常用名为 value,使用时可省略属性名
int count() default 1;
String[] tags() default {};
}
- 使用自定义注解
public class Demo {
@MyAnnotation(value = "test", count = 3, tags = {"a", "b"})
public void myMethod() {
// ...
}
// 如果只有 value 属性且需要赋值,可以省略 value=
@MyAnnotation("shortcut")
public void anotherMethod() {}
}
- 过反射读取注解(运行时处理)
import java.lang.reflect.Method;
public class AnnotationProcessor {
public static void main(String[] args) throws Exception {
Method method = Demo.class.getMethod("myMethod");
if (method.isAnnotationPresent(MyAnnotation.class)) {
MyAnnotation anno = method.getAnnotation(MyAnnotation.class);
System.out.println("value: " + anno.value());
System.out.println("count: " + anno.count());
System.out.println("tags: " + Arrays.toString(anno.tags()));
}
}
}