java.lang.annotation
@Retention(RetentionPolicy.SOURCE) // 僅源碼保留,編譯器丟棄(如 @Override、@SuppressWarnings)
@Retention(RetentionPolicy.CLASS) // 編譯入 class,運行時不可見(默認)
@Retention(RetentionPolicy.RUNTIME) // 運行時可見,反射可獲取(自定義注解常用)
@Target(ElementType.TYPE) // 類、接口、枚舉、注解
@Target(ElementType.FIELD) // 字段、枚舉常量
@Target(ElementType.METHOD) // 方法
@Target(ElementType.PARAMETER) // 方法參數
@Target(ElementType.CONSTRUCTOR) // 構造器
@Target(ElementType.LOCAL_VARIABLE) // 局部變量
@Target(ElementType.ANNOTATION_TYPE)// 注解類型
@Target(ElementType.PACKAGE) // 包
@Target(ElementType.TYPE_PARAMETER) // 類型參數 (Java 8+)
@Target(ElementType.TYPE_USE) // 類型使用處 (Java 8+)
可組合:@Target({ElementType.METHOD, ElementType.FIELD})
標記後,javadoc 會包含該注解信息。
子類自動繼承父類的該注解(僅針對 TYPE 級別注解)。
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface HelloWorld {
String name() default ""; // 必須有默認值或使用時指定
int priority() default 1;
String[] tags() default {}; // 數組類型
}
規則:
public abstractdefault,不能為 null
public class SayHello {
@HelloWorld(name = "小明", priority = 2, tags = {"greeting", "demo"})
public void sayHello(String name) {
System.out.println(name + " say hello world!");
}
@HelloWorld(name = "默認優先級")
public void sayHi() { ... }
}
public class AnnotationParser {
public void parse(Class> clazz) {
try {
Object instance = clazz.getDeclaredConstructor().newInstance();
for (Method method : clazz.getDeclaredMethods()) {
// 獲取方法上的指定注解
HelloWorld annotation = method.getAnnotation(HelloWorld.class);
if (annotation != null) {
String name = annotation.name();
int priority = annotation.priority();
String[] tags = annotation.tags();
System.out.printf("方法: %s, name=%s, priority=%d, tags=%s%n",
method.getName(), name, priority, Arrays.toString(tags));
// 調用方法
method.invoke(instance, name);
}
}
} catch (Exception e) {
throw new RuntimeException("解析失敗", e);
}
}
public static void main(String[] args) {
new AnnotationParser().parse(SayHello.class);
}
}
// 容器注解 (Java 8+ @Repeatable)
@Repeatable(HelloWorlds.class)
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface HelloWorld { ... }
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface HelloWorlds {
HelloWorld[] value();
}
// 使用
@HelloWorld(name = "A")
@HelloWorld(name = "B")
public void multiAnnotated() { ... }
// 解析
HelloWorlds container = method.getAnnotation(HelloWorlds.class);
if (container != null) {
for (HelloWorld hw : container.value()) { ... }
}
// 或 Java 8+ 直接獲取數組
HelloWorld[] annos = method.getAnnotationsByType(HelloWorld.class);
@Retention(RUNTIME)@Target,避免濫用enabled() 而非 isEnabled()AnnotationProcessor 編譯期處理,降低運行時開銷