Java 注解类型详解:从入门到实战
2026/8/31 23:37:19 网站建设 项目流程

1. 什么是注解

注解(Annotation)是 Java 5 引入的一种元数据机制,它允许我们在代码中添加结构化、机器可读的元数据信息。注解本身不直接影响程序运行逻辑,但可以被编译器、框架和工具在编译期或运行期读取并处理。

简单来说,注解就是给代码贴的「标签」,这些标签可以被各种工具识别并触发相应的行为。

2. 注解的分类

Java 注解按生命周期和作用范围可以分为以下几类:

2.1 按生命周期分类

  • 源码级注解(SOURCE):仅在源码中存在,编译时被丢弃。典型代表是@Override@SuppressWarnings
  • 编译期注解(CLASS):保留到编译后的 class 文件中,但运行时不可见。常用于字节码增强工具。
  • 运行期注解(RUNTIME):不仅保留在 class 文件中,还能在运行时通过反射读取。这是框架开发中最常用的一类,如@Autowired@RequestMapping

2.2 按用途分类

  • 标记注解:不含任何成员变量,仅用于标记,如@Deprecated
  • 单值注解:只有一个成员变量,通常命名为value,使用时可以省略变量名,如@SuppressWarnings("unchecked")
  • 完整注解:包含多个成员变量,使用时需显式指定,如@RequestMapping(value = "/user", method = RequestMethod.GET)

3. 自定义注解

3.1 定义注解

使用@interface关键字定义注解:

importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)public@interfaceLogExecutionTime{Stringvalue()default"";booleanprintArgs()defaultfalse;}

3.2 注解成员变量

注解的成员变量以方法的形式声明,可以指定默认值:

public@interfaceApiInfo{Stringauthor()default"unknown";Stringversion()default"1.0.0";String[]tags()default{};}

成员变量支持的类型包括:基本类型、String、Class、枚举、注解以及这些类型的数组。

4. 元注解

元注解是用于修饰其他注解的注解,Java 提供了以下四种核心元注解:

元注解作用
@Retention指定注解的生命周期(SOURCE/CLASS/RUNTIME)
@Target指定注解可以修饰的目标(类、方法、字段等)
@Documented标记该注解应被 javadoc 文档化
@Inherited标记该注解可被子类继承

4.1 @Target 的可选值

ElementType.TYPE// 类、接口、枚举ElementType.FIELD// 字段ElementType.METHOD// 方法ElementType.PARAMETER// 参数ElementType.CONSTRUCTOR// 构造器ElementType.LOCAL_VARIABLE// 局部变量ElementType.ANNOTATION_TYPE// 注解类型ElementType.PACKAGE// 包ElementType.TYPE_PARAMETER// 类型参数ElementType.TYPE_USE// 类型使用处

5. 注解的读取

5.1 运行时反射读取

importjava.lang.reflect.Method;publicclassAnnotationDemo{@LogExecutionTime(value="getUser",printArgs=true)publicvoidgetUser(Stringid){System.out.println("查询用户:"+id);}publicstaticvoidmain(String[]args)throwsException{Methodmethod=AnnotationDemo.class.getMethod("getUser",String.class);if(method.isAnnotationPresent(LogExecutionTime.class)){LogExecutionTimeannotation=method.getAnnotation(LogExecutionTime.class);System.out.println("注解值:"+annotation.value());System.out.println("是否打印参数:"+annotation.printArgs());}}}

5.2 编译期处理(APT)

编译期注解处理器通过javax.annotation.processing包实现,常用于生成代码,如 Lombok、MapStruct 等框架。

6. 注解的典型应用场景

6.1 框架开发

Spring、MyBatis 等框架大量使用注解简化配置:

@RestController@RequestMapping("/api/users")publicclassUserController{@GetMapping("/{id}")publicUsergetUser(@PathVariableLongid){returnuserService.findById(id);}}

6.2 代码生成

通过注解处理器在编译期自动生成样板代码,减少手写工作量。

6.3 参数校验

publicclassUser{@NotNull(message="用户名不能为空")@Size(min=2,max=20,message="用户名长度必须在 2-20 之间")privateStringname;}

7. 注解与反射的配合

注解本身只是元数据,真正发挥作用需要配合反射或注解处理器。运行时注解的典型处理流程如下:

定义注解

标注到目标代码

程序启动

反射扫描注解

是否命中目标注解

读取注解属性

执行对应逻辑

跳过处理

8. 注意事项

  • 注解成员变量不能使用包装类型,必须使用基本类型。
  • 注解不能继承其他注解,但可以通过元注解@Inherited实现类级别的继承效果。
  • 运行时注解的反射读取有一定性能开销,高频调用场景需谨慎使用。
  • 注解成员变量名不能使用element等保留关键字。

9. 总结

Java 注解是一种强大的元数据机制,它让代码更加简洁、可读性更强,也是现代 Java 框架的基石。掌握注解的定义、元注解的使用以及反射读取方式,是深入理解 Spring 等主流框架的必备技能。建议读者动手实践一个自定义注解,结合反射实现一个简单的日志切面,加深理解。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询