JAVA基础--注解(Annotation)
JAVA基础--注解(Annotation)
一、概念
注解:提供一种为程序提供元数据(metadata)的方法
基本原则:注解不能直接干扰程序代码的运行,无论删除还是增加注解,代码都能够正常运行。
注解元素数据类型:
- 所有基本类型
- String
- Class
- enum
- Annotation
- 以上类型的数组
应用:
1、编写文档:通过代码里标识的元数据生成文档
2、代码分析:通过代码里标识的元数据对代码进行分析
3、编译检查:通过代码里标识的元数据让编译器能进行基本的编译检查,如@Override
二、标准注解
@Override
保证编译时候Override函数的申明正确性
@Deprecated
标记过时方法,如果使用该注解,编译时会报编译警告
与javadoc里的@deprecated
有相同的功能,准确的说它还不如@deprecated
,因为它不支持参数
@SuppressWarnings
关闭特定的警告信息
@SuppressWarnings(value={"unchecked", "rawtypes"})
class Test{
@SuppressWarnings("unchecked")
public void testMethod(){
@SuppressWarnings("rawtypes")
List list = new ArrayList();
}
}
常见参数:
参数 | 含义 |
---|---|
deprecation | 关闭使用了过时的类或方法时的警告 |
unchecked | 关闭执行了未检查的转换时的警告 |
fallthrough | 关闭当switch程序块直接进入下一情况而未break的警告 |
path | 关闭在类路径、源文件路径等中有不存在的路径时的警告 |
serial | 关闭当在可序列化的类上缺少 serialVersionUID 定义时的警告 |
finally | 关闭任何finally子句不能正常完成时的警告 |
all | 关闭关于以上所有情况的警告 |
@FunctionalInterface
java8支持,标识一个匿名函数或函数式接口
函数式接口(Functional Interface)就是有且仅有一个抽象方法,但有多个非抽象方法的接口。
三、元注解
负责注解其他的注解
@Retention
表示需要在什么级别保存该注解信息
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
RetentionPolicy value();
}
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
String[] value();
}
RetentionPolicy是一个枚举类型,它定义了被@Retention
修饰的注解所支持的保留级别
生命周期类型 | 描述 |
---|---|
RetentionPolicy.SOURCE | 编译时被丢弃,不包含在类文件中 |
RetentionPolicy.CLASS | JVM加载时被丢弃,包含在类文件中,默认值 |
RetentionPolicy.RUNTIME | 由JVM加载,包含在类文件中,在运行时可以被获取到 |
@Target
该注解可以用于什么地方,指定作用域
源码:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
/**
* Returns an array of the kinds of elements an annotation type
* can be applied to.
* @return an array of the kinds of elements an annotation type
* can be applied to
*/
ElementType[] value();
}
ElementType是一个枚举类型,它定义了被@Target
修饰的注解可以作用的范围
Target类型 | 作用 |
---|---|
TYPE | 类、接口(包括注解类型)、枚举 |
FIELD | 字段或属性(包括枚举) |
METHOD | 方法函数 |
PARAMETER | 方法的参数 |
CONSTRUCTOR | 构造函数 |
LOCAL_VARIABLE | 局部变量 |
ANNOTATION_TYPE | 注解类型 |
PACKAGE | 包 |
TYPE_PARAMETER | java8,类型变量 |
TYPE_USE | java8,任何使用类型的语句中 |
@Documented
生成文档信息的时候保留注解,对类作辅助说明
@Inhertied
允许子类继承父类中的注释
@Repeatable
表示注解可以重复使用,java8新增
当我们需要重复使用某个注解时,希望利用相同的注解来表现所有的形式时,我们可以借助@Repeatable注解。
四、注解处理器
如果没有用来读取注解的方法和工作,那么注解也就不会比注释更有作用了。使用反射机制的API可以帮助我们快速的构造自定义注解处理器。
提取注解:java.lang.reflect.AnnotatedElement
接口
isAnnotationPresent
判断该程序元素上是否存在包含指定类型的注解,存在返回true,否则返回false;getAnnotation
返回该程序元素上存在的指定类型的注解。如果该类型注解不存在,则返回null;getAnnotations
返回该程序元素上存在的所有注解;getAnnotationsByType
返回该程序元素上存在的指定类型的所有注解。如果该类型注解不存在,返回长度为0的数组。java8;getDeclaredAnnotations
返回直接存在于此元素上的所有注解;getDeclaredAnnotation
返回直接存在于此元素上的指定类型的注解。如果该类型注解不存在,则返回null。java8;getDeclaredAnnotationsByType
返回直接存在于此元素上的指定类型所有注解 。如果该类型注解不存在,返回长度为0的数组。java8;
示例:
/** 自定义注解 **/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TestAnnotation {
public String name() default "";
}
/** 注解使用 **/
public class TestClass {
@TestAnnotation(name = "测试")
public void testMethod() {
System.out.println(" testMethod run ");
}
}
/** 注解处理器 **/
public class TestHandel{
public static void main(String[] arg){
Class clazz = TestClass.class;
Method method = clazz.getMethod("testMethod");
if(method.isAnnotationPresent(TestAnnotation.class)){
TestAnnotation annotation = method.getAnnotation(TestAnnotation.class);
// 打印注解属性
System.out.println(annotation.name());
// 控制新建的TestClass对象,执行 testMethod 方法
method.invoke(new TestClass());
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!