Java自定义注解详解

发布于:2025-05-01 ⋅ 阅读:(14) ⋅ 点赞:(0)

一、注解基础

注解(Annotation)是Java 5引入的特性,它提供了一种为程序元素(类、方法、变量等)添加元数据的方式。注解本身不会影响程序的执行,但可以被编译器、运行时环境或其他工具读取并处理。

注解的作用

  1. 提供编译器信息 - 帮助编译器检测错误或抑制警告
  2. 编译时和部署时处理 - 生成代码、XML文件等
  3. 运行时处理 - 通过反射读取注解信息,实现特定功能

Java内置注解

Java提供了几个内置注解,如:

  • @Override - 标记方法覆盖父类方法
  • @Deprecated - 标记已过时的元素
  • @SuppressWarnings - 抑制编译器警告
  • @FunctionalInterface - 标记函数式接口
  • @SafeVarargs - 抑制与可变参数相关的警告

二、元注解

元注解是用于注解其他注解的注解。Java提供了几个重要的元注解:

@Retention

定义注解的保留策略:

public enum RetentionPolicy {
   
    SOURCE,    // 仅在源代码中保留,编译时丢弃
    CLASS,     // 保留在编译后的类文件中,但JVM运行时不保留(默认行为)
    RUNTIME    // 保留至运行时,可通过反射API访问
}

@Target

指定注解可应用的程序元素类型:

public enum ElementType {
   
    TYPE,               // 类、接口、枚举
    FIELD,              // 字段、枚举常量
    METHOD,             // 方法
    PARAMETER,          // 方法参数
    CONSTRUCTOR,        // 构造函数
    LOCAL_VARIABLE,     // 局部变量
    ANNOTATION_TYPE,    // 注解类型
    PACKAGE,            // 包
    TYPE_PARAMETER,     // 类型参数(Java 8)
    TYPE_USE,           // 类型使用(Java 8)
    MODULE              // 模块(Java 9)
}

@Documented

指示注解应该被包含在JavaDoc中。

@Inherited

指示注解可以被子类继承。

@Repeatable(Java 8)

指示注解可以在同一元素上多次使用。

三、创建自定义注解

基本语法

自定义注解的语法与接口定义类似,使用@interface关键字:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
   
    // 注解属性声明
}

注解属性

注解可以包含属性(也称为元素):

public @interface MyAnnotation {
   
    String value();           // 无默认值的属性
    String name() default ""; // 带默认值的属性
    int age() default 0;
    String[] roles() default {
   };
}

注解属性的类型限制:

  • 基本类型(int, float, boolean等)
  • String
  • Class
  • 枚举类型
  • 注解类型
  • 以上类型的数组

使用自定义注解

@MyAnnotation(value = "测试", name = "张三", age = 25, roles = {
   "admin", "user"})
public void someMethod() {
   
    // 方法实现
}

// 当只有value属性需要设置时,可以简写
@MyAnnotation("测试")
public void anotherMethod() {
   
    // 方法实现
}

四、注解的处理方式

1. 编译时处理

使用注解处理器(Annotation Processor)在编译时处理注解。这通常用于代码生成、编译时验证等。

示例:创建一个简单的编译时注解处理器

// 定义注解
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
public @interface Builder {
   
}

// 创建注解处理器
@SupportedAnnotationTypes("com.example.Builder")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class BuilderProcessor extends AbstractProcessor {
   
    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
   
        // 处理逻辑
        return true;
    }
}

2. 运行时处理(反射)

使用Java反射API在运行时读取和处理注解。

示例:运行时处理注解

// 定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Test {
   
    boolean enabled() default true;
}

// 使用注解
public class MyTest {
   
    @Test(enabled = true)
    public void testMethod1() {
   
        // 测试代码
    }
    
    @Test(enabled = false)
    public void testMethod2() {
   
        // 测试代码
    }
}

// 处理注解
<