Java注解学习大纲:从基础到实践,掌握内置、自定义与框架注解

news/2025/3/30 19:28:46/文章来源:https://www.cnblogs.com/java-note/p/18795811

一、注解基础

  1. 注解的概念
  • 定义:注解是一种特殊的标记,可以附加在包、类、方法、成员变量等程序元素上,用于为代码提供额外的元数据信息,这些信息可以在编译时、运行时被读取和处理。
  • 与注释的区别:注释主要用于对代码的说明,供程序员阅读理解;注解则可以被程序读取和处理,对程序的运行和开发过程有实际作用。
  1. 注解的分类
  • 按作用范围分类
    • 元注解:用于定义其他注解的注解,如@Target@Retention等,它们决定了注解的使用目标和生命周期。
    • 内置注解:Java语言内置的一些注解,如@Override@Deprecated等,具有特定的语义和功能。
    • 自定义注解:由程序员根据需要定义的注解,用于满足特定的业务需求或开发规范。
  • 按使用时机分类
    • 编译时注解:在代码编译阶段被处理的注解,例如通过注解处理器生成代码或进行编译检查。
    • 运行时注解:在程序运行时可以通过反射机制获取的注解,用于动态地获取和处理注解信息。
  1. 注解的元数据
  • 元数据是注解中存储的信息,可以是简单的值(如字符串、基本数据类型等),也可以是复杂的结构(如数组、枚举等)。元数据的定义和使用方式决定了注解的功能和灵活性。

二、Java内置注解

  1. @Override
  • 作用:用于标记方法覆盖(重写)父类方法的情况。如果一个方法被标记为@Override,但并没有正确覆盖父类方法(例如方法签名不匹配),编译器会报错,从而帮助程序员避免错误地覆盖方法。
  • 使用场景:在子类中重写父类的方法时使用,确保方法的正确覆盖,提高代码的可读性和正确性。
  1. @Deprecated
  • 作用:用于标记某个程序元素(如类、方法、成员变量等)已过时,不推荐使用。当其他代码使用了被标记为@Deprecated的元素时,编译器会发出警告,提示开发者使用替代的实现。
  • 使用场景:当某些代码在新的版本中被替换或有更好的替代方案时,使用@Deprecated来标记旧的代码,以便逐步淘汰和更新代码。
  1. @SuppressWarnings
  • 作用:用于抑制编译器警告。可以指定要忽略的警告类型,例如忽略未使用的变量警告、类型安全警告等。这在某些情况下可以避免编译器产生不必要的警告干扰开发,但需要谨慎使用,避免掩盖潜在的错误。
  • 使用场景:当代码中存在某些无法避免的警告,且经过评估这些警告不会影响程序的正确性和性能时,可以使用@SuppressWarnings来抑制这些警告。

三、元注解

  1. @Target
  • 作用:用于定义注解可以应用的目标程序元素类型。例如,可以指定注解只能用于类、方法、成员变量等特定的元素,从而限制注解的使用范围,避免注解被错误地使用在不支持的元素上。
  • 使用场景:在定义自定义注解时,通过@Target指定注解的使用目标,例如ElementType.METHOD表示注解只能用于方法。
  1. @Retention
  • 作用:用于定义注解的生命周期,即注解在什么阶段可以被保留。生命周期分为三种:
    • RetentionPolicy.SOURCE:注解仅在源代码阶段保留,在编译时会被丢弃,不会进入字节码文件。
    • RetentionPolicy.CLASS:注解在编译时会被保留到字节码文件中,但运行时无法通过反射获取。
    • RetentionPolicy.RUNTIME:注解在运行时可以通过反射机制获取,具有最高的保留级别。
  • 使用场景:在定义自定义注解时,根据注解的使用需求选择合适的保留策略。例如,如果需要在运行时通过反射获取注解信息,则应使用RetentionPolicy.RUNTIME
  1. @Documented
  • 作用:用于标记注解是否应该被包含在Java文档中。当注解被标记为@Documented时,注解的文档信息会出现在Java文档中,方便其他开发者了解注解的用途和使用方法。
  • 使用场景:在定义具有公共意义且需要被文档化的注解时使用,例如框架提供的注解等。
  1. @Inherited
  • 作用:用于标记注解是否可以被子类继承。当注解被标记为@Inherited时,子类会自动继承父类上的该注解,从而避免在子类中重复声明相同的注解。
  • 使用场景:在定义一些具有继承特性的注解时使用,例如某些配置注解或标记注解等。

四、Java标准注解(JSR-250)

  1. @Resource
  • 作用:用于注入资源,通常用于注入JNDI(Java Naming and Directory Interface)资源,如数据源、连接池等。它可以根据名称或类型查找资源,并将其注入到目标对象中。
  • 使用场景:在需要注入外部资源(如数据库连接池)的场景中使用,简化资源的获取和管理。
  1. @PostConstruct
  • 作用:用于标记一个方法在依赖注入完成后执行。被标记的方法会在对象创建并完成依赖注入后被调用,通常用于初始化操作。
  • 使用场景:在需要在对象初始化后执行一些额外的逻辑(如设置默认值、初始化状态等)时使用。
  1. @PreDestroy
  • 作用:用于标记一个方法在对象销毁前执行。被标记的方法会在对象被销毁之前被调用,通常用于清理资源。
  • 使用场景:在需要在对象销毁前释放资源(如关闭文件流、断开数据库连接等)时使用。

五、Spring框架中的常用注解

  1. @Component
  • 作用:用于标记一个类为Spring的组件,使该类成为Spring容器管理的Bean。Spring会自动扫描并实例化带有@Component注解的类,并将其注册到Spring容器中。
  • 使用场景:在定义普通的组件类(如工具类、服务类等)时使用,让Spring管理这些类的生命周期和依赖关系。
  1. @Controller
  • 作用:用于标记一个类为Spring MVC的控制器。它是@Component的特化,专门用于处理Web请求。Spring会将带有@Controller注解的类注册为控制器,并处理HTTP请求。
  • 使用场景:在定义Web控制器类时使用,用于处理用户的HTTP请求并返回响应。
  1. @Service
  • 作用:用于标记一个类为服务层组件。它是@Component的特化,通常用于定义业务逻辑层的类。Spring会管理带有@Service注解的类,并提供事务管理等功能。
  • 使用场景:在定义业务逻辑类时使用,用于封装业务逻辑操作。
  1. @Repository
  • 作用:用于标记一个类为数据访问层组件。它是@Component的特化,通常用于定义数据访问类(如DAO)。Spring会管理带有@Repository注解的类,并提供数据访问相关的功能,如异常转换等。
  • 使用场景:在定义数据访问类时使用,用于操作数据库或其他存储系统。
  1. @Autowired
  • 作用:用于自动注入Spring容器中的Bean。可以标记在成员变量、构造函数或方法上,Spring会根据类型或名称查找匹配的Bean并注入。
  • 使用场景:在需要注入依赖的场景中使用,简化依赖注入的配置,提高开发效率。
  1. @Qualifier
  • 作用:用于指定注入的具体Bean的名称。当存在多个相同类型的Bean时,可以通过@Qualifier指定注入哪一个Bean。
  • 使用场景:在存在多个相同类型的Bean,需要精确指定注入对象时使用。
  1. @Value
  • 作用:用于注入配置文件中的值。可以将配置文件中的属性值注入到成员变量中,方便在代码中使用配置信息。
  • 使用场景:在需要从配置文件中读取配置值(如数据库连接信息、应用配置等)时使用。
  1. @Configuration
  • 作用:用于标记一个类为Spring的配置类。它类似于传统的XML配置文件,可以通过注解的方式定义Bean和配置信息。
  • 使用场景:在使用注解配置Spring应用时使用,替代或补充XML配置文件。
  1. @Bean
  • 作用:用于定义一个Bean。可以标记在方法上,方法的返回值会被注册为Spring容器中的Bean。
  • 使用场景:在@Configuration类中定义Bean时使用,用于创建和配置Bean。
  1. @Transactional
  • 作用:用于声明事务属性。可以标记在类或方法上,指定事务的传播行为、隔离级别、超时时间等属性,从而实现事务管理。
  • 使用场景:在需要管理事务的业务逻辑方法或类上使用,确保数据操作的完整性。

六、自定义注解

  1. 定义自定义注解
  • 语法:使用@interface关键字定义注解,类似于定义接口。可以在注解中定义成员变量(即元数据),成员变量的类型可以是基本数据类型、字符串、枚举、类、注解等。

  • 示例

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyAnnotation {String value() default "";int timeout() default 1000;
    }
    
  1. 注解的成员变量
  • 默认值:可以为注解的成员变量指定默认值,如果未指定默认值,则在使用注解时必须为该成员变量赋值。
  • 无参数注解:如果注解没有成员变量,则称为无参数注解,使用时只需在目标元素上标记即可。
  1. 使用自定义注解
  • 标记目标元素:在需要使用注解的程序元素上标记自定义注解,并根据需要为注解的成员变量赋值。

  • 示例

    @MyAnnotation(value = "example", timeout = 2000)
    public void myMethod() {// 方法实现
    }
    
  1. 处理自定义注解
  • 编译时处理:通过注解处理器(Annotation Processor)在编译阶段读取和处理注解信息,例如生成代码、进行编译检查等。

  • 运行时处理:通过反射机制在运行时获取注解信息,并根据注解的元数据执行相应的逻辑。

  • 示例

    Method method = MyClass.class.getMethod("myMethod");
    MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
    if (annotation != null) {String value = annotation.value();int timeout = annotation.timeout();// 根据注解信息执行逻辑
    }
    

七、注解的实践与应用

  1. 代码规范和文档化
  • 使用注解来标记代码的规范和约定,例如标记方法的预期行为、参数的约束等,提高代码的可读性和可维护性。
  • 通过@Documented注解将注解信息包含在Java文档中,为其他开发者提供注解的使用说明。
  1. 框架开发
  • 在开发框架时,使用注解来定义框架的扩展点和配置方式,例如Spring框架通过注解实现依赖注入、事务管理等功能。
  • 利用注解处理器在编译阶段生成代码或进行校验,提高框架的灵活性和易用性。
  1. 代码生成
  • 使用注解处理器在编译阶段根据注解信息生成代码,例如生成代理类、序列化代码等,减少手写代码的工作量。
  1. 运行时动态处理
  • 在运行时通过反射获取注解信息,根据注解的元数据动态地执行逻辑,例如实现权限校验、日志记录等功能。
  1. 性能优化
  • 合理使用注解的保留策略,避免在运行时加载不必要的注解信息,减少内存占用和性能开销。
  1. 案例分析
  • 分析一些开源框架(如Spring、Hibernate等)中注解的使用方式和实现原理,学习如何在实际项目中高效地使用注解。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/906655.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RabbitMQ通过代码实现交换机分发模式

首先导入rabbitMQ的依赖:<!-- https://mvnrepository.com/artifact/com.rabbitmq/amqp-client --><dependency><groupId>com.rabbitmq</groupId><artifactId>amqp-client</artifactId><version>5.25.0</version></depende…

vue复基本语法

以下为你用表格形式呈现 Vue 3 基本语法:类别 语法示例 说明模板语法文本插值 <div>{{ message }}</div> 使用双大括号将数据显示在模板中属性绑定 <img :src="imageUrl" alt="示例图片"> :src 是 v-bind:src 的简写,用于动态绑定属性…

vue3-webseek网页版AI问答|Vite6+DeepSeek+Arco流式ai聊天打字效果

2025 AI实战vue3+deepseek+arcoDesign仿DeepSeek/豆包网页版AI聊天助手。 vue3-web-deepseek 实战网页PC版智能AI对话,基于vite6+vue3.5+openAI对接DeepSeek-Chat聊天对话模型。实现流动式打字返回效果、支持亮色+暗黑主题、各种代码高亮、本地会话存储等功能。🐬技术栈编码…

仓库呆滞物料堆积如山?十年的仓库主管跟我说了这五点

今天咱们聊聊一个经常让很多仓库管理者头疼的问题—— 仓库呆滞物料堆积 。 说实话,仓库呆滞物料堆得满满的,不仅占用宝贵的仓储空间,还让企业的资金周转变得紧张,真的是个大麻烦! 不过,之前我和一位拥有 十年经验的仓库主管 聊了聊,得到了很多宝贵的经验,特别是在如何…

【汇总】sqlcmd 命令选项说明-MSSQL2012

一、原始帮助D:\>sqlcmd /? Microsoft (R) SQL Server 命令行工具 版本 11.0.2100.60 NT x64 版权所有 (c) 2012 Microsoft。保留所有权利。用法: Sqlcmd [-U 登录 ID] [-P 密码][-S 服务器] [-H 主机名] [-E 可信连接][-N 加密连…

导入SpaceClaim的iges模型尺寸被放大1000倍的问题

ANSYS APDL 和 Workbench 联合仿真中,导入 Workbench 的 iges 模型尺寸被放大1000倍问题的解决方案问题 ANSYS APDL 和 Workbench 联合仿真时,导入 SpaceClaim 的 .iges 模型尺寸被放大 1000 倍数。 如 APDL 生成的尺寸为 10 mm(注:此处的 mm 是在 APDL 编码中设置的一致单…

Linux的vim编辑器

Linux的vi/vim编辑器 命令模式 编辑模式 输入模式 vi/ vim编辑器的基本操作Linux的vi/vim编辑器基本概念:vim文本编辑器,是由vi编辑器发展演变过来的文本编辑器,因其具有使用简单、功能强大、是 Linux 众多发行版的默认文本编辑器。很多人习惯将 vim 称为 vi,其实 vim 是 v…

高度场流体模拟

【USparkle专栏】如果你深怀绝技,爱“搞点研究”,乐于分享也博采众长,我们期待你的加入,让智慧的火花碰撞交织,让知识的传递生生不息!一、原理参考这个论文:《Real-time Simulation of Large Bodies of Water with Small Scale Details》 核心是这两个公式: 我在这篇《…

Navicat将微软数据库MS-SQLServer表内容导入MySQL数据库

前言全局说明一、说明 1.1 环境: Windows 7 旗舰版 MSSQL 2012 Navicat for MySQL 10.1.7二、MySQL准备 用 Navicat 在 mysql 新建数据库,要和 MSSQL 数据库同名注意:编码也要一致2.1 mysql 新建数据 空白处新,建 test 数据库,2.2 数据库右键查看在mysql里新建数据库编码三…

深度解析:通过 AIBrix 多节点部署 DeepSeek-R1 671B 模型

本文详细介绍了如何通过 AIBrix 分布式推理平台实现 DeepSeek-R1 671B 的多节点部署。DeepSeek-R1 通过渐进式训练框架展现出优秀的逻辑推理能力 —— 在 6710 亿总参数量中,其动态激活的 370 亿参数与 128k 上下文窗口,使其在复杂任务处理中表现卓越。然而,如此庞大的模型规…

玄机靶场 第一章 应急响应-webshell查杀

玄机靶场 第一章 应急响应-webshell查杀 1.黑客webshell里面的flag flag2. 黑客使用的什么工具的shell github地址的md5 flag 哥斯拉webshell的特征3.黑客隐藏shell的完整路径的md5 flag{md5} 注 : /xxx/xxx/xxx/xxx/xxx.xxx 发现隐藏4.黑客免杀马完整路径 md5 flag 查看这是一…

玄机靶场 第一章 应急响应-Linux日志分析

玄机靶场 第一章 应急响应-Linux日志分析 1.有多少IP在爆破主机ssh的root帐号,如果有多个使用","分割 /var/log/auth.log里面存放了相关的登录信息 直接下载看根据user=root发现三个ip 网上发现神奇妙妙脚本 cat auth.log.1 | grep -a "Failed password for ro…