一、注解基础
注解(Annotation)是Java 5引入的特性,它提供了一种为程序元素(类、方法、变量等)添加元数据的方式。注解本身不会影响程序的执行,但可以被编译器、运行时环境或其他工具读取并处理。
注解的作用
- 提供编译器信息 - 帮助编译器检测错误或抑制警告
- 编译时和部署时处理 - 生成代码、XML文件等
- 运行时处理 - 通过反射读取注解信息,实现特定功能
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() {
// 测试代码
}
}
// 处理注解
<