Java 注解属性
什么是注解属性
在Java中,注解(Annotation)不仅可以作为简单的标记存在,还可以携带数据。这些携带的数据就是通过注解属性来实现的。注解属性使得注解可以更加灵活地传递信息,使代码变得更加可配置和强大。
备注
注解属性有点类似于方法参数,允许我们在使用注解时提供额外的信息。
注解属性的基本语法
注解属性在定义注解时声明,语法类似于无参数方法:
public @interface AnnotationName {
数据类型 属性名() default 默认值;
}
属性类型限制
Java注解的属性类型必须是以下之一:
- 基本数据类型(int, float, boolean等)
- String类型
- Class类型
- 枚举类型
- 注解类型
- 以上类型的数组
定义带属性的注解
让我们看一个简单的例子,定义一个带有属性的注解:
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface TestInfo {
// 属性声明
String author() default "Unknown";
String date();
int revision() default 1;
String[] comments() default {};
}
在这个例子中:
author()
属性有一个默认值 "Unknown"date()
属性没有默认值,这意味着在使用注解时必须提供该属性值revision()
属性的默认值是1comments()
属性是一个字符串数组,默认为空数组
使用带属性的注解
使用带有属性的注解时,需要为没有默认值的属性提供值,也可以选择性地为有默认值的属性提供值:
public class AnnotationDemo {
@TestInfo(
author = "Alice",
date = "2023-10-20",
revision = 2,
comments = {"初始版本", "修复bug"}
)
public void testMethod() {
// 方法实现
System.out.println("测试方法执行");
}
@TestInfo(
date = "2023-10-21" // author和revision使用默认值
)
public void anotherMethod() {
// 方法实现
System.out.println("另一个方法执行");
}
}
特殊属性:value
如果一个注解只有一个属性,并且这个属性名为value
,那么在使用注解时,可以省略属性名和等号,直接提供值:
// 定义只有value属性的注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Description {
String value(); // 单一属性名为value
}
// 使用注解时可以简化
public class SimpleDemo {
@Description("这是一个测试方法") // 等同于 @Description(value = "这是一个测试方法")
public void testMethod() {
// 方法实现
}
}
注解属性的访问
通过反射API,我们可以在运行时访问注解的属性值:
import java.lang.reflect.Method;
public class AnnotationReaderDemo {
public static void main(String[] args) {
try {
// 获取AnnotationDemo类的testMethod方法
Method method = AnnotationDemo.class.getMethod("testMethod");
// 检查方法是否包含TestInfo注解
if (method.isAnnotationPresent(TestInfo.class)) {
// 获取注解实例
TestInfo testInfo = method.getAnnotation(TestInfo.class);
// 访问注解属性
System.out.println("作者: " + testInfo.author());
System.out.println("日期: " + testInfo.date());
System.out.println("修订版本: " + testInfo.revision());
System.out.println("备注: ");
for (String comment : testInfo.comments()) {
System.out.println("- " + comment);
}
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}
输出结果:
作者: Alice
日期: 2023-10-20
修订版本: 2
备注:
- 初始版本
- 修复bug
数组类型属性
当属性类型是数组时,有两种方式可以提供值:
// 方式1:使用大括号提供多个值
@TestInfo(
date = "2023-10-22",
comments = {"值1", "值2", "值3"}
)
public void method1() { }
// 方式2:如果只有一个值,可以省略大括号
@TestInfo(
date = "2023-10-22",
comments = "单个值" // 等同于 comments = {"单个值"}
)
public void method2() { }