当前位置: 首页 > ai >正文

注解的使用和自定义

在 Java 里,注解是一种元数据形式,它能够为程序元素(像类、方法、字段等)添加补充信息。这些信息不会对程序的运行逻辑造成影响,但可以在编译阶段、运行阶段被读取并加以利用。下面为你详细介绍注解的使用方法以及自定义注解的编写方式:

内置注解

Java 自身提供了一些内置注解,常见的有:

  • @Override:此注解用于标明某个方法是对父类方法的重写。
  • @Deprecated:表示某个程序元素已过时,不建议再使用。
  • @SuppressWarnings:用于抑制编译器产生的警告信息。
  • @FunctionalInterface:用于标记某个接口是函数式接口。

元注解

元注解的作用是对注解进行注解,Java 定义了以下几种元注解:

  • @Retention:它指定了注解的保留策略,可选值有:
    • RetentionPolicy.SOURCE:注解仅在源代码阶段保留,编译时会被编译器丢弃。
    • RetentionPolicy.CLASS:注解会被保留到编译后的 class 文件中,但运行时不会被 JVM 读取。
    • RetentionPolicy.RUNTIME:注解在运行时可以被 JVM 读取,能够通过反射机制获取注解信息。
  • @Target:用于限定注解可以应用的程序元素类型,例如:
    • ElementType.TYPE:可以应用于类、接口、枚举等类型。
    • ElementType.METHOD:只能应用于方法。
    • ElementType.FIELD:只能应用于字段。
    • 还有其他多种可选值,如PARAMETERCONSTRUCTOR等。
  • @Documented:该注解表明它所修饰的注解会被包含在 JavaDoc 文档中。
  • @Inherited:此注解使得子类可以继承父类的注解。
  • @Repeatable:从 Java 8 开始支持,允许在同一个程序元素上重复使用同一个注解。

自定义注解的定义

下面通过一个示例来展示如何定义自定义注解:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;// 定义一个可以在类和方法上使用的运行时注解
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {// 定义注解的属性,带有默认值String value() default "";int count() default 1;Class<?> category() default Void.class;
}

注解属性的定义

在自定义注解时,需要注意以下几点:

  • 注解属性的返回类型只能是以下几种:基本数据类型、String、Class、枚举类型、注解类型,以及这些类型的数组。
  • 定义属性的语法为type attributeName() default defaultValue;,其中default部分是可选的。
  • 如果注解中只有一个属性,通常将其命名为value,这样在使用注解时可以省略属性名。

注解的使用

以下是使用自定义注解的示例:

@MyAnnotation(value = "Example", count = 3, category = MyClass.class)
public class MyClass {@MyAnnotation("Method Annotation")public void myMethod() {// 方法实现}
}

通过反射读取注解

当注解的保留策略为RUNTIME时,可以利用反射机制来读取注解信息:

import java.lang.reflect.Method;public class AnnotationProcessor {public static void main(String[] args) throws NoSuchMethodException {// 获取类上的注解Class<?> clazz = MyClass.class;if (clazz.isAnnotationPresent(MyAnnotation.class)) {MyAnnotation classAnnotation = clazz.getAnnotation(MyAnnotation.class);System.out.println("Class Annotation: " + classAnnotation.value());System.out.println("Count: " + classAnnotation.count());System.out.println("Category: " + classAnnotation.category().getName());}// 获取方法上的注解Method method = clazz.getMethod("myMethod");if (method.isAnnotationPresent(MyAnnotation.class)) {MyAnnotation methodAnnotation = method.getAnnotation(MyAnnotation.class);System.out.println("Method Annotation: " + methodAnnotation.value());}}
}

重复注解的使用(Java 8+)

Java 8 引入了对重复注解的支持,使用方式如下:

import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;// 定义重复注解容器
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface Filters {Filter[] value();
}// 定义可重复注解
@Repeatable(Filters.class)
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface Filter {String value();
}// 使用重复注解
public class RepeatingAnnotationsExample {@Filter("auth")@Filter("logging")public void process() {// 方法实现}
}// 读取重复注解
public class RepeatingAnnotationsProcessor {public static void main(String[] args) throws NoSuchMethodException {Method method = RepeatingAnnotationsExample.class.getMethod("process");Filter[] filters = method.getAnnotationsByType(Filter.class);for (Filter filter : filters) {System.out.println("Filter: " + filter.value());}}
}

注解的应用场景

注解在实际开发中有多种应用场景,例如:

  • 编译时检查:像@Override注解,用于确保方法正确重写了父类方法。
  • 代码生成:例如 Lombok 库通过注解自动生成 Getter、Setter 等代码。
  • 运行时处理:Spring 框架使用@Autowired@Component等注解实现依赖注入。
  • 序列化:Jackson 库使用@JsonProperty等注解控制 JSON 序列化和反序列化的行为。
  • 测试框架:JUnit 使用@Test@BeforeEach等注解标记测试方法和配置方法。

最佳实践

在使用注解和自定义注解时,建议遵循以下最佳实践:

  • 保持注解的简洁性,避免在一个注解中定义过多的属性。
  • 为注解属性设置合理的默认值,减少使用注解时的冗余代码。
  • 为注解提供清晰的文档说明,解释其用途和属性的含义。
  • 优先使用运行时注解(RetentionPolicy.RUNTIME),以便在运行时能够利用反射机制进行处理。
  • 考虑使用重复注解来提高代码的可读性。
http://www.xdnf.cn/news/9111.html

相关文章:

  • Composer 常规操作说明与问题处理
  • 【部署】读取制度类txt文件导入dify的父子分段知识库
  • Kubernetes 1.33您需要了解的和升级新功能
  • 爬虫学习-Scrape Center spa6 超简单 JS 逆向
  • 二叉树遍历
  • 打破壁垒:国内软件业产品与技术割裂困局及工程师产品思维重塑
  • 无网络docker镜像迁移
  • OSC协议简介、工作原理、特点、数据的接收和发送
  • 5月26日day37打卡
  • 【大模型Pre-Training实战总结】实现Qwen3增量预训练,Lora训练与合并
  • 修改mysql 数据库密码记录
  • MySQL数据库零基础入门教程:从安装配置到数据查询全掌握
  • 2025年AIR SCI1区TOP,具有新变异策略和外部存档机制mLSHADE-SPACMA+数值优化与点云配准,深度解析+性能实测
  • 【2025】harbor仓库搭建
  • MAR:无需量化的掩码自回归图像生成模型
  • Windows Server 2016 下封禁端口规避高危漏洞的测试实践
  • 通过chrome插件自动生成博客评论,高效发外链
  • 15.2【基础项目】使用 TypeScript 实现密码显示与隐藏功能
  • wsl2 安装 nodejs
  • 人工智能与教育科技:2025年个性化学习的新模式
  • (C++17) 未捕获异常 uncaught_exceptions
  • Java基础 Day21
  • 从无符号长整型数中提取字节
  • 【Redis】Redis安装
  • 红外遥控器接收实验:CubeMX配置底层软件
  • 基于vue框架的动漫网站noww0(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
  • 【windwos】文本编辑器Notepad++ 替代品Notepad--
  • 汇川伺服软件设置提示使能冲突
  • 深入解读Qwen3技术报告(五):后训练对齐
  • Linux系统调用深度剖析