后端知识点:自定义注解的常用元注解
1. @Target({ElementType.PARAMETER})
这个注解是用来指定你的自定义注解可以用在什么地方。
- @Target:是“目标”的意思。它限定了注解的应用范围。
- ElementType.PARAMETER:这是一个枚举常量,代表“参数”。
所以,@Target({ElementType.PARAMETER}) 的意思就是:你正在定义的这个注解,只能被用来修饰方法的参数。
ElementType 还有很多其他的值,例如:
- TYPE:可以用于类、接口或枚举。
- FIELD:可以用于类的成员变量(字段)。
- METHOD:可以用于方法。
- CONSTRUCTOR:可以用于构造函数。
如果一个注解被定义为只能用于参数,那么当你想把它用在类或者方法上时,编译器就会报错。
简单来说: @Target 规定了注解的“贴”在哪里。ElementType.PARAMETER 就是规定了只能“贴”在方法的参数上。
2. @Retention(RetentionPolicy.RUNTIME)
这个注解是用来指定你的自定义注解的生命周期,也就是说,注解的信息能保留到什么时候。
- @Retention:是“保留”的意思。它决定了注解在哪个阶段有效。
- RetentionPolicy.RUNTIME:这也是一个枚举常量,代表“运行时”。
所以,@Retention(RetentionPolicy.RUNTIME) 的意思就是:你定义的这个注解,不仅在源代码(.java文件)和编译后的字节码(.class文件)中存在,在程序运行时(Runtime)也同样存在。 这使得我们可以通过反射(Reflection)机制在程序运行时动态地获取到这个注解和它的信息。
RetentionPolicy 共有三个值:
- SOURCE:注解只在源代码中保留,编译器编译时会将其丢弃,不会包含在 .class 文件中。通常用于做一些编译前的检查,如 @SuppressWarnings。
- CLASS:这是默认的策略。注解会被保留到 .class 文件中,但是在Java虚拟机(JVM)运行时会被丢弃,所以无法在运行时通过反射获取。
- RUNTIME:注解会被保留到运行时,JVM加载类之后,仍然可以通过反射访问到该注解。这是最常用的一种策略,很多框架(如Spring)都依赖于此在运行时实现特定功能。
简单来说: @Retention 决定了注解能“活”多久。RetentionPolicy.RUNTIME 就是让它一直“活”到程序运行的时候。
3. @Documented
这个注解的作用比较简单,它是用来指定你的自定义注解是否应该被包含在 Javadoc 中。
- @Documented:是“被文档化的”意思。
默认情况下,我们自定义的注解是不会出现在 javadoc 工具生成的API文档中的。如果给一个自定义注解加上了 @Documented,那么当其他类使用了这个自定义注解时,生成的API文档里就会把这个注解也显示出来。
这有助于开发者理解被注解的代码所具有的特殊含义或功能。
简单来说: @Documented 决定了在生成API文档时,要不要把这个注解也一起展示出来。
总结
这三个元注解联合起来,定义了一个新的注解,这个新的注解具有以下特性:
- 使用位置:只能用在方法的参数上 (@Target(ElementType.PARAMETER))。
- 生命周期:在程序运行时依然有效,可以通过反射来获取和处理 (@Retention(RetentionPolicy.RUNTIME))。
- 文档生成:在使用 javadoc 工具生成文档时,这个注解会被包含进去 (@Documented)。
举个例子:
假设你定义了一个叫 @NotBlank 的注解:
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface NotBlank {
String message() default "参数不能为空";
}
然后你可以在一个方法中使用它:
public void login(String username, @NotBlank String password) {
// ... 登录逻辑
}
在这里,@NotBlank 注解就只能用于像 password 这样的参数。因为它的保留策略是 RUNTIME,所以你可以编写一个切面(AOP)或者拦截器,在 login 方法被调用时,通过反射检查 password 参数上是否有 @NotBlank 注解,如果有,就判断该参数是否为空,从而实现参数校验的功能。同时,生成的API文档也会标明 password 参数上使用了 @NotBlank 注解。

浙公网安备 33010602011771号