Java注解
什么是Java注解
Java 注解(Annotation)是一种元数据(metadata)的形式,它提供了一种将元数据与程序元素(类、接口、方法、变量等)相关联的方式。Java 注解可以为程序元素添加额外的信息和指令,以便编译器、工具和框架可以更好地理解和处理程序。
为什么使用注解
- 提高代码的可读性和可维护性:通过注解可以为代码添加更多的信息和说明,使得代码更加易于理解和维护。例如,通过注解可以标记某个方法是测试方法,在代码中就可以清晰地看到这个方法的作用和用途,方便开发人员进行代码调试和维护。
- 减少重复性代码:通过注解可以定义一些通用的代码逻辑和模式,避免在不同的代码中重复编写相同的逻辑和代码,提高了代码的复用性和可扩展性。例如,通过注解可以定义一个事务处理器,避免在不同的方法中编写相同的事务处理代码。
- 提高代码的可靠性和安全性:通过注解可以对代码进行更严格的检查和限制,避免一些潜在的错误和安全漏洞。例如,通过注解可以限制某个方法的访问权限,避免非授权用户访问该方法。
- 简化配置和部署:通过注解可以在代码中添加部署和配置信息,避免繁琐的配置和部署过程。例如,通过注解可以标记某个类或方法需要被 Spring 容器管理,容器就可以自动扫描和装配这些类和方法。
知识点补充
元数据:
元数据是描述数据的数据,即数据的属性、定义和结构等信息,它们不是直接操作数据的内容,而是提供了一些额外的信息和指令,以便对数据进行更好的处理和管理。
我们经常在Java程序中见到,比如@Override, @Resource等
注解分类
- 标准注解(
Standard Annotation):Java 语言内置的注解,包括@Override、@Deprecated、@SuppressWarnings等。这些注解可以直接在代码中使用,用于提供元数据和指令,以便编译器、工具和框架可以更好地处理程序。(用于辅助编译器,工具框架,不会被编译进.class文件) - 元注解(
Meta-Annotation):用于注解其他注解的注解,包括@Target、@Retention、@Documented、@Inherited等。元注解可以用于控制注解的使用方式、生命周期、文档化等方面,可以提高注解的可用性和可读性。 - 自定义注解(Custom Annotation):由开发人员根据自己的需要定义的注解,可以用于描述程序元素的含义、用途和特性,以及为程序添加指令和元数据信息。自定义注解可以提高程序的可读性、可维护性和灵活性,使得程序可以更好地适应不同的环境和需求。
元注解
元注解(Meta-Annotation)是用于注解其他注解的注解,用于控制注解的使用方式、生命周期、文档化等方面,可以提高注解的可用性和可读性。
Java 语言内置了几个元注解,包括:
提示: ElementType是一个枚举类
-
@Retention:用于指定注解的生命周期,它有一个值域 ElementType,表示注解的生命周期可以是 SOURCE(源代码级别可用)、CLASS(编译器将注解记录在类文件中,但不会在运行时保留)、RUNTIME(编译器将注解记录在类文件中,并在运行时保留在内存中)。 -
@Target:用于指定注解的作用范围,它有一个值域 ElementType,表示注解可以用于哪些程序元素上,例如类、方法、字段、参数等。- 类或接口:
ElementType.TYPE; - 字段:
ElementType.FIELD; - 方法:
ElementType.METHOD; - 构造方法:
ElementType.CONSTRUCTOR; - 方法参数:
ElementType.PARAMETER。
实际上
@Target定义的value是ElementType[]数组,只有一个元素时,可以省略数组的写法。 - 类或接口:
-
@Documented:用于指定注解是否需要被文档化,如果一个注解被 @Documented 注解,则它在文档中也会出现,否则不会出现。 -
@Inherited:用于指定注解是否可以被继承,如果一个注解被 @Inherited 注解,则它可以被子类继承,否则不能被子类继承。
元注解可以帮助程序员更好地控制和使用自定义注解,提高注解的可用性和可读性。程序员也可以根据自己的需要定义不同类型的元注解,以适应不同的环境和需求。
写一个注解
- 确定注解的作用范围和属性:首先需要确定注解可以作用于哪些程序元素上,例如类、方法、字段、参数等,然后需要确定注解的属性,例如字符串、整数、布尔类型等。
- 定义注解:使用 @interface 关键字来定义注解,可以在注解中定义一些属性和方法。注解的属性可以有默认值,也可以设置为必填项,注解的方法可以用于对属性进行校验和处理,或者用于生成额外的元数据信息。
- 定义元注解(可选):如果需要控制注解的使用方式、生命周期、文档化等方面,可以定义自定义元注解来注解其他注解。
- 使用注解:在程序中的类、方法、字段、参数等元素上添加注解,可以使用注解的属性来指定注解的值。
- 处理注解:在程序中可以使用反射机制来获取和处理注解,例如获取注解的属性值、根据注解生成代码等。
// 客户端测试
public class Client {
public static void main(String[] args) throws NoSuchMethodException {
MyAnnotationProcessor annotationProcessor = new MyAnnotationProcessor();
annotationProcessor.process(MyClass.class.getMethod("myMethod"));
}
}
// 定义注解,作用于方法
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface MyAnnotation {
String value() default "default value";
}
// 使用注解
class MyClass {
@MyAnnotation("时间节点")
public void myMethod() {
// 正常的逻辑代码
}
}
// 处理注解
class MyAnnotationProcessor {
// 这个方法用于读取注解,并对注解内容进行处理
public void process(Method method) {
if (method.isAnnotationPresent(MyAnnotation.class)) {
// 获得注解对象,注解最后也是被编译为对象
MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
System.out.println("我获得了注解的参数值:" + annotation.value());
}
}
}
输出:
我获得了注解的参数值:时间节点