如何在 Java 中自定义注解?

108 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

什么是注解?

代码中的特殊标记,这些标记可以在编译、类加载、运行时被读取,并执行相应的处理。

注解的作用?

编写文档、代码分析、编译检查等。

最常见的注解:

@Override 注解,它的作用是告诉编译器这个方法是不是重写父类的方法。

@Deprecated 注解,它的作用是提示我们这个方法可能由于多重原因而被弃用,例如使用它可能会导致错误,或者在未来的版本中进行不兼容的更改或删除等。

元注解

java中的元注解包括:@Target @Documented @Inherited @Native @Repeatable @Retention

它们可以在 JDK11 中的 java.lang.annotation 包中可以找到定义。

@Target注解标识可以应用的Java元素的类型:

类型描述
ElementType.TYPE类、接口(包括注解类型)或枚举的声明
ElementType.FIELD字段声明(包括枚举常量)
ElementType.METHOD方法声明
ElementType.PARAMETER形参声明
ElementType.CONSTRUCTOR构造方法声明
ElementType.LOCAL_VARIABLE局部变量声明
ElementType.ANNOTATION_TYPE注解类型声明
ElementType.PACKAGE包声明
ElementType.TYPE_PARAMETER类型参数声明
ElementType.TYPE_USE类型的使用
ElementType.MODULE模块声明

@Retention注解表明生命周期

生命周期描述
RetentionPolicy.SOURCE将被编译器丢弃
RetentionPolicy.CLASS将被记录在class文件中,但不需要在JVM运行时保留。默认的生命周期是CLASS
RetentionPolicy.RUNTIME将被记录在class文件中,在JVM运行时保留,可以通过反射读取到

如何自定义注解?

首先需要明确注解的格式:

 元注解
 @interface 注解名(){
     注解需要的参数
 }

步骤

  1. @interface自动继承 java.lang.annotation.Annotation 注解
  2. 添加几乎固定的元注解
  3. 添加使用自定义注解时候的参数

示例

  1. 自定义注解
 package com.gitee.shiayanga.annotation;
 ​
 import java.lang.annotation.*;
 ​
 /**
  * @author LiYang
  */
 @Documented
 @Target(ElementType.TYPE)
 @Retention(RetentionPolicy.RUNTIME)
 public @interface AnnotationTest {
     String code() default "0000";
     String desc() default "这是一个自定义注解测试";
 }
  1. 验证注解
 package com.gitee.shiayanga.test;
 ​
 import com.gitee.shiayanga.annotation.AnnotationTest;
 ​
 import java.util.Arrays;
 ​
 /**
  * TODO
  *
  * @author LiYang
  * @version 1.0
  * @date 2022/5/22 22:17
  */
 @AnnotationTest(code = "6666")
 public class TestAnnotation {
     public static void main(String[] args) throws NoSuchFieldException {
         TestAnnotation testAnnotation = new TestAnnotation();
         Class<? extends TestAnnotation> aClass = testAnnotation.getClass();
         System.out.println(Arrays.toString(aClass.getAnnotations()));
         // 判断TestAnnotation类上面是不是有 AnnotationTest 注解
         if (aClass.isAnnotationPresent(AnnotationTest.class)) {
             System.out.println("TestAnnotation 类上使用了 AnnotationTest 注解!");
             // 获取testAnnotation对象上的注解
             AnnotationTest annotation = aClass.getAnnotation(AnnotationTest.class);
             System.out.println(annotation.code() + annotation.desc());
         }
     }
 }
  1. 执行结果
 "D:\Program Files\Java\jdk-11.0.11\bin\java.exe" "-javaagent:D:\Program Files\JetBrains\IntelliJ IDEA 2021.2.3\lib\idea_rt.jar=5983:D:\Program Files\JetBrains\IntelliJ IDEA 2021.2.3\bin" -Dfile.encoding=UTF-8 -classpath D:\OpenSource\java-demos\target\classes com.gitee.shiayanga.test.TestAnnotation
 [@com.gitee.shiayanga.annotation.AnnotationTest(desc="这是一个自定义注解测试", code="6666")]
 TestAnnotation 类上使用了 AnnotationTest 注解!
 6666这是一个自定义注解测试
 ​
 进程已结束,退出代码0