目录
- 一、注解概述
-
- [1.1 什么是注解](#1.1 什么是注解)
- [1.2 注解的作用](#1.2 注解的作用)
- 二、注解基础
-
- [2.1 内置注解](#2.1 内置注解)
- [2.2 元注解(用于定义注解的注解)](#2.2 元注解(用于定义注解的注解))
- 三、自定义注解定义
-
- [3.1 基本语法](#3.1 基本语法)
- [3.2 注解元素类型限制](#3.2 注解元素类型限制)
- 四、元注解详解
-
- [4.1 @Target - 指定使用位置](#4.1 @Target - 指定使用位置)
- [4.2 @Retention - 指定保留策略](#4.2 @Retention - 指定保留策略)
- [4.3 例子](#4.3 例子)
- 五、注解使用示例
-
- [5.1 字段验证注解](#5.1 字段验证注解)
- [5.2 API接口注解](#5.2 API接口注解)
- 六、注解处理器
-
- [6.1 编译时处理(APT)](#6.1 编译时处理(APT))
- [6.2 运行时处理(反射)](#6.2 运行时处理(反射))
- 七、高级特性
-
- [7.1 重复注解(Java 8+)](#7.1 重复注解(Java 8+))
- [7.2 类型注解(Java 8+)](#7.2 类型注解(Java 8+))
一、注解概述
1.1 什么是注解
注解(Annotation)是Java 5引入的一种元数据机制,用于为代码添加额外的信息,这些信息可以被编译器、运行时环境或其他工具读取和处理。
1.2 注解的作用
编译器检查(如@Override)
代码生成(如Lombok)
运行时处理(如Spring注解)
文档生成(如@Deprecated)
二、注解基础
2.1 内置注解
clike
@Override // 检查方法是否重写父类方法
@Deprecated // 标记已过时
@SuppressWarnings // 抑制编译器警告
@FunctionalInterface // 函数式接口
2.2 元注解(用于定义注解的注解)
java
@Target // 指定注解可以应用的位置
@Retention // 指定注解的保留策略
@Documented // 是否包含在Javadoc中
@Inherited // 是否允许子类继承
@Repeatable // 是否可重复使用(Java 8+)
三、自定义注解定义
3.1 基本语法
java
// 定义注解
public @interface MyAnnotation {
// 注解元素(属性)
String value() default "default";
int count() default 0;
String[] tags() default {};
}
// 使用注解
@MyAnnotation(value = "test", count = 5, tags = {"a", "b"})
public class MyClass {
@MyAnnotation
public void method() {}
}
其中的属性值都是有括号的value()
3.2 注解元素类型限制
注解元素只能是以下类型:
基本类型(int、boolean等)
String
Class
enum
Annotation
以上类型的数组
四、元注解详解
4.1 @Target - 指定使用位置
java
@Target(ElementType.TYPE) // 类、接口、枚举
@Target(ElementType.FIELD) // 字段
@Target(ElementType.METHOD) // 方法
@Target(ElementType.PARAMETER) // 参数
@Target(ElementType.CONSTRUCTOR) // 构造器
@Target(ElementType.LOCAL_VARIABLE) // 局部变量
@Target(ElementType.ANNOTATION_TYPE)// 注解
@Target(ElementType.PACKAGE) // 包
@Target(ElementType.TYPE_PARAMETER) // 类型参数(Java 8+)
@Target(ElementType.TYPE_USE) // 类型使用(Java 8+)
// 允许多个位置
@Target({ElementType.TYPE, ElementType.METHOD})
4.2 @Retention - 指定保留策略
java
@Retention(RetentionPolicy.SOURCE) // 仅源码,编译后丢弃
@Retention(RetentionPolicy.CLASS) // 编译到class文件,运行时不可见
@Retention(RetentionPolicy.RUNTIME) // 运行时可见,可通过反射读取
4.3 例子
java
import java.lang.annotation.*;
// 定义一个运行时注解,可用于类和方法
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface CustomAnnotation {
String name() default "";
String description();
int version() default 1;
Status status() default Status.ACTIVE;
// 嵌套注解
Author[] authors() default {};
// 枚举
enum Status {
ACTIVE, INACTIVE, DEPRECATED
}
// 注解中的注解
@interface Author {
String name();
String email() default "";
}
}
五、注解使用示例
5.1 字段验证注解
java
// 定义验证注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Validation {
boolean required() default false;
int minLength() default 0;
int maxLength() default Integer.MAX_VALUE;
String regex() default "";
String message() default "验证失败";
}
// 使用注解
public class User {
@Validation(required = true, minLength = 2, maxLength = 20,
message = "用户名长度2-20字符")
private String username;
@Validation(required = true, regex = "^(?=.*[A-Za-z])(?=.*\\d).{6,}$",
message = "密码必须包含字母和数字,至少6位")
private String password;
@Validation(regex = "^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$",
message = "邮箱格式不正确")
private String email;
}
5.2 API接口注解
java
// 定义REST API注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ApiEndpoint {
String path();
HttpMethod method() default HttpMethod.GET;
String description() default "";
boolean requireAuth() default false;
String[] roles() default {};
enum HttpMethod {
GET, POST, PUT, DELETE, PATCH
}
}
// 使用注解
@RestController
@RequestMapping("/api/users")
public class UserController {
@ApiEndpoint(
path = "/{id}",
method = ApiEndpoint.HttpMethod.GET,
description = "根据ID获取用户",
requireAuth = true,
roles = {"ADMIN", "USER"}
)
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
return userService.getUser(id);
}
}
六、注解处理器
6.1 编译时处理(APT)
java
// 定义注解处理器
@SupportedAnnotationTypes("com.example.Validation")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class ValidationProcessor extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
for (TypeElement annotation : annotations) {
Set<? extends Element> elements =
roundEnv.getElementsAnnotatedWith(annotation);
for (Element element : elements) {
// 处理注解,生成代码等
Validation validation = element.getAnnotation(Validation.class);
// 生成验证代码
}
}
return true;
}
}
6.2 运行时处理(反射)
java
// 注解处理器工具类
public class AnnotationProcessor {
public static void processValidation(Object obj) throws IllegalAccessException {
Class<?> clazz = obj.getClass();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(Validation.class)) {
field.setAccessible(true);
Validation validation = field.getAnnotation(Validation.class);
Object value = field.get(obj);
// 执行验证逻辑
validateField(field.getName(), value, validation);
}
}
}
private static void validateField(String fieldName, Object value,
Validation validation) {
if (validation.required() && value == null) {
throw new ValidationException(fieldName + "不能为空");
}
if (value instanceof String) {
String strValue = (String) value;
if (strValue.length() < validation.minLength()) {
throw new ValidationException(validation.message());
}
if (strValue.length() > validation.maxLength()) {
throw new ValidationException(validation.message());
}
if (!validation.regex().isEmpty()) {
if (!strValue.matches(validation.regex())) {
throw new ValidationException(validation.message());
}
}
}
}
}
七、高级特性
7.1 重复注解(Java 8+)
java
// 1. 定义容器注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Roles {
Role[] value();
}
// 2. 定义可重复注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(Roles.class)
public @interface Role {
String value();
}
// 3. 使用
@Role("ADMIN")
@Role("USER")
public class User {
// 等价于 @Roles({@Role("ADMIN"), @Role("USER")})
}
7.2 类型注解(Java 8+)
java
// 定义类型注解
@Target(ElementType.TYPE_USE)
@Retention(RetentionPolicy.RUNTIME)
public @interface NonNull {
}
// 使用
public class TypeAnnotationExample {
private @NonNull String name; // 字段类型
public List<@NonNull String> filter(
@NonNull List<String> list) { // 参数和泛型类型
return list.stream()
.filter(s -> s != null)
.collect(Collectors.toList());
}
}