Java注解需用@Retention(RetentionPolicy.RUNTIME)声明才能在运行时通过反射获取属性值,调用getAnnotation()获得实例后直接调用其方法即可读取各类型属性值。

Java 注解在运行时通过反射获取属性值,关键在于:注解必须用 @Retention(RetentionPolicy.RUNTIME) 声明,然后用反射 API(如 getAnnotation()、getDeclaredAnnotations())获取注解实例,再调用其方法访问属性值。
确保注解可被运行时读取
只有声明为 RetentionPolicy.RUNTIME 的注解才能在运行时通过反射访问。编译期(SOURCE)或类加载期(CLASS)的注解无法获取。
示例定义一个可运行时读取的注解:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME) // 必须有这一行
public @interface LogExecution {
String value() default "";
int retryTimes() default 3;
boolean async() default false;
}
在目标元素上使用注解
把注解加在类、方法、字段等目标上。例如加在某个方法上:
立即学习“Java免费学习笔记(深入)”;
public class UserService {
@LogExecution(value = "用户登录", retryTimes = 2, async = true)
public void login(String username) {
// ...
}
}
用反射获取注解并读取属性值
通过 Class 或 Method 等反射对象调用 getAnnotation(XXX.class) 获取注解实例,然后像调用普通接口方法一样获取属性值。
获取并使用示例:
UserService service = new UserService();
Method method = service.getClass().getMethod("login", String.class);
// 获取注解实例
LogExecution annotation = method.getAnnotation(LogExecution.class);
if (annotation != null) {
System.out.println("value: " + annotation.value()); // 输出:用户登录
System.out.println("retryTimes: " + annotation.retryTimes()); // 输出:2
System.out.println("async: " + annotation.async()); // 输出:true
}
注意点:
- 如果注解不存在,
getAnnotation()返回null,需判空 - 注解属性本质是接口方法,调用即返回定义的值(含默认值)
- 若要获取所有注解(包括重复注解),可用
getDeclaredAnnotations()或配合@Repeatable
处理自定义注解中的数组、枚举、Class 类型属性
注解支持多种返回类型,反射读取方式一致,直接调用对应方法即可:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Config {
String[] servers() default {"localhost"};
LogLevel level() default LogLevel.INFO;
Class<?> processor() default Void.class;
}
读取示例:
Config config = clazz.getAnnotation(Config.class); String[] servers = config.servers(); // 返回 String 数组 LogLevel level = config.level(); // 返回枚举值 Class<?> procClass = config.processor(); // 返回 Class 对象
这些类型无需特殊转换,JVM 自动完成解析和装箱/实例化。


















