注解
What
从JDK5开始,Java增加对元数据的支持,也就是注解。注解与注释是有一定区别的,可以把注解理解为代码里的特殊标记,这些标记可以在编译,类加载,运行时被其他程序(eg.编译器等)读取,并执行相应的处理。通过注解开发人员可以在不改变原有代码和逻辑的情况下在源代码中嵌入补充信息。
- 注解是以“@注解名”在代码中存在的,还可以添加一些参数值
(eg.@SuppressWarnings(value=“unchecked”)) - 最初开发人员通过配置文件告诉类如何运行,有了注解后,我们就可以通过反射技术获取类中的注解,通过注解告诉类如何运行
- 注解可以附加在package、class、method、field等上面,相当于给他们添加了额外的辅助信息,且注解与代码的映射可以为多对一。
内置注解
Java提供了5个基本的注解,分别是:
-
@Override(限定父类重写方法):定义在java.lang.Override中,此注释只适用于修饰方法,表示一个方法声明打算重写超类中的另一个方法声明;
-
@Deprecated(标示已过时):定义在java.lang.Deprecated中,此注释可以用于修饰方法、属性、类,表示不鼓励程序员使用这样的元素,通常是因为它很危险或者存在更好的选择;
-
@SuppressWarnings(抑制编译器警告):定义在java.lang.SuppressWarnings中,用来抑制编译时的警告信息
- 与前两个注释不同的是,该注解需要添加一个参数才能够正确使用,且所需参数都是提前定义好的,只需选择使用。
- @SuppressWarnings(“all”)
- @SuppressWarnings(“unchecked”)
- @SuppressWarnings(value={“unchecked”,“deprecation”})
- …
-
@SafeVarargs(“堆污染”警告):堆污染,即把不带泛型的对象赋给一个带泛型的对象;
- 由于不带泛型时默认会给泛型设定为object,也就是什么类型都可以往里面塞,那不带泛型的对象也就无法赋给一个带泛型的对象
-
@FunctionalInterface(函数式接口):保证这个接口只有一个抽象方法,注意这个只能修饰接口
- 函数式接口中只有一个抽象方法(可以包含多个默认方法或多个static方法)
- 函数式接口体内只能声明常量字段和抽象方法,并且被隐式声明为public,static,final。
- 函数式接口里面不能有私有的方法或变量。
元注解 meta-annotation
除了自定义注解之外,JDK提供了4个标准的用于对注解类型进行注解的注解类,我们称之为元注解meta-annotation。
- @Target
- @Retention
- @Documented
- @Inherited
@Target注解
作用:描述注解的使用范围(即:被修饰的注解可以用在什么地方)。
Target注解用来说明那些被它所注解的注解类可修饰的对象范围:注解可以用于修饰 packages、types(类、接口、枚举、注解类)、类成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数),在定义注解类时使用了@Target 能够更加清晰的知道它能够被用来修饰哪些对象,它的取值范围定义在ElementType 枚举中。
public enum ElementType {
TYPE, // 类、接口、枚举类
FIELD, // 成员变量(包括:枚举常量)
METHOD, // 成员方法
PARAMETER, // 方法参数
CONSTRUCOR, // 构造方法
LOCAL_VARIABLE, // 局部变量
ANNOTATION_TYPE, // 注解类
PACKAGE, // 可用于修饰:包
TYPE_PARAMETER, // 类型参数,JDK 1.8 新增
TYPE_USE // 使用类型的任何地方,JDK 1.8 新增
}
@Retention注解
作用:描述注解保留的时间范围(即:被描述的注解在所修饰类中可以被保留到何时)。
Reteniton注解用来限定所注解的注解类在注解到其他类上以后,可被保留到何时,一共有三种策略,定义在RetentionPolicy枚举中,常用策略为RUNTIME。
public enum RetentionPolicy {
SOURCE, // 源文件保留
CLASS, // 编译期保留,默认值
RUNTIME // 运行期保留,可通过反射去获取注解信息
}
注:
- 编译器不会记录下带@Retention(RetentionPolicy.SOURCE)元注解方法的注释信息;
- 编译器会使用RuntimeInvisibleAnnotations 和RuntimeVisibleAnnotations 属性记录带@Retention(RetentionPolicy.CLASS)和@Retention(RetentionPolicy.RUNTIME)元注解方法的注释信息
@Documented注解
作用:描述在使用 javadoc 工具为类生成帮助文档时是否要保留其注解信息。
@Inherited注解
作用:使被修饰的注解具有继承性(即,如果某个类使用了被@Inherited修饰的注解,则其子类将自动具有该注解)。
自定义注解
使用关键字@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口。
- @interface用来声明一个注解,格式:public @interface 注解名{定义内容};
- 注解中每一个方法实际上是声明了一个配置参数,方法名就是参数名,返回值类型就是参数的类型(返回值只能是基本类型、Class、String、enum);
- 可以通过default来声明参数的默认值
- 如果只有一个参数成员,一般参数名为value;
- 注解元素必须有值,我们定义注解元素时,经常使用空字符串、0作为默认值。