本文已参与「新人创作礼」活动,一起开启掘金创作之路。
一、概述
位于 java.lang.annotation,接口 Annotation,出生于 JDK 1.5
我们使用注解以及注解能起到作用,需要有三方参与(注意:不是实习那个三方):
- 注解标签本身
- 被贴的程序元素(类、字段、构造器、方法、参数、包)
- 由第三方的程序使用反射手段赋予注解特殊功能
简单记,就是自己、敌人以及打敌人的技能
二、常见的内置注解
@Override
- 只能作用于方法
- 作用:表示该方法是重写父类的方法,会进行验证
这家伙大伙肯定很熟了,写接口抽象方法的实现时,实现方法上面就有这么一个注解
@Deprecated
- 可以作用于变量、方法、类
- 作用:表示该作用域代码已过时,不建议使用,但能够使用
这家伙大伙应该也熟,比如Object#finalize()、Thread#stop()等等,我们在使用贴有这个注解的方法时,就会看到有一条删除线在这个方法上
@SuppressWarnings
- 可以作用于变量、方法、类
- 作用:抑制警告,只是看不到警告,不代表没有警告
有时候我们看到一些警告时,可以这么写但不建议这么写,但你偏要这么写时,就会出现黄色警告,这时用上这么一个注解,就舒服多了
@SafeVarargs
- 作用于一个方法中同时出现可变参数和泛型
- 作用:用于抑制对污染发出的警告,但问题依然存在
这个瞅瞅就好了
@FunctionalInterface
- 作用于接口
- 作用:用于检测该接口是否满足函数式接口的要求(接口中有且只有一个抽象方法)
这个是 JDK 1.8 增加的⼀个注解,用于检查接口是否符合要求,用法如下:
@FunctionalInterface public interface MyRunnable { void run(); }
三、元注解
负责注解其它注解的注解称为元注解,用来提供对其它 annotation 类型作说明
分类
@Target
- 用于描述注解的范围,即该注解能用在什么地方
- 说明了 Annotation 所修饰的对象范围
- ElementType
PACKAGE包TYPE类、接口或枚举ANNOTATION_TYPE注解CONSTRUCTOR构造方法METHOD方法FIELD字段(包含枚举常量)LOCAL_VARIABLE局部变量(如循环变量、catch参数)PARAMETER方法参数
@Retention
- 用于描述注解的生命周期,即注解保留时间的长短
- RetentionPolicy
SOURCE:表示该注解只存在于源文件中,不会被编译到字节码中CLASS:表示该注解会被编译到字节码中,但JVM不加载注解RUNTIME:表示该注解会被编译到字节码中并进入JVM,可以通过反射读取
@Documented
- 表示作为公共 API,能够被工具文档化
- 标注注解,没有成员
其实也就是贴上这个注解的注解,在使用到具体的对象(类、方法等)上时,所生成的文档会显示出所贴的注解
@Inherited
- 表示自动继承注释类型
四、注解的语法
使用@Interface声明一个注解,每一个方法实际上声明了一个配置参数,方法名为参数名,返回值类型为参数类型(只能是基本类型、Class、String、enum)
public @interface 注解名 {
// 注解参数
}
注解参数支持的数据类型
- 基本数据类型
- String 类型
- Class 类型
- enum 类型
- Annotation 类型
- 以上所有类型的数组
注解元素必须有确定的值,可以在定义注解的默认值中指定,也可以使用注解时指定,非基本数据类型的注解元素的值不可为 null
五、自定义注解
使用@Interface标识,默认继承 java.lang.annotation.Annotation 接口,在定义注解时,不能继承其它注解或接口
步骤
- 创建注解文件
- 说明该注解能够使用的位置和保存的时期
- 将注解贴到能够贴的位置
- 为注解传递参数
/**
* 用于标记某个映射方法是否需要登录访问
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiredLogin {
}