快速深入了解Java注解Annotation
用@interface来修饰的接口文件就是注解.
他也可以拥有成员变量
根据注解的参数个数可以分为以下几类
- 标记注解
- 单值注解
- 完整注解
注解按照使用方式又分为以下几种:
- JDK内置系统注解
- 元注解
- 自定义注解
/--------------------------------------/
打开java.lang.annotation包,可以看到里面有这几个注解:
- Documented(元注解)
- Inherited(元注解)
- Retention(元注解)
- Target(元注解)
元注解
先来解释一下什么是元注解:作用就是负责注解其他注解,java 5.0定义了4个meta-annotation类型,用来提供对其他的annotation类型做说明。
元注解之Documented
它的含义就是:注解是否应当被包含在 JavaDoc 文档中,被@Documented 注解修饰的注解,当我们执行 JavaDoc 文档打包时会被保存进 doc 文档,反之将在打包时丢弃.
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}
元注解之Inherited
它的含义就是:是否允许子类继承被@Inherited注解的注解,@Inherited 注解修饰的注解是具有可继承性的,也就说我们的注解修饰了一个类,而该类的子类将自动继承父类的该注解.
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
}
元注解之Retention
它的含义就是: 注解的生命周期,用于指明当前注解的生命周期
同时他有一个value属性,该属性由枚举RetentionPolicy指定
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
/**
* Returns the retention policy.
* @return the retention policy
*/
RetentionPolicy value();
}
public enum RetentionPolicy {
/**
* Annotations are to be discarded by the compiler.
*/
SOURCE,//当前注解编译期可见,不会写入 class 文件
/**
* Annotations are to be recorded in the class file by the compiler
* but need not be retained by the VM at run time. This is the default
* behavior.
*/
CLASS,//类加载阶段丢弃,会写入 class 文件
/**
* Annotations are to be recorded in the class file by the compiler and
* retained by the VM at run time, so they may be read reflectively.
*
* @see java.lang.reflect.AnnotatedElement
*/
RUNTIME//永久保存,可以反射获取
}
@Retention 注解指定了被修饰的注解的生命周期
- SOURCE是只能在编译期可见,编译后会被丢弃
- CLASS会被编译器编译进 class 文件中,无论是类或是方法,乃至字段,他们都是有属性表的,而 JAVA 虚拟机也定义了几种注解属性表用于存储注解信息,但是这种可见性不能带到方法区,类加载时会予以丢弃
- RUNTIME则是永久存在的可见性。
元注解之Target
它的含义就是: 注解的作用目标
@Target 用于指明被修饰的注解最终可以作用的目标是谁,也就是指明,你的注解到底是用来修饰方法的,修饰类的,还是用来修饰字段等属性的.
它与@Retention注解一样,都有一个value属性,但是一个数组.
@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();
}
public enum ElementType {
/** Class, interface (including annotation type), or enum declaration */
TYPE,//允许被修饰的注解作用在类、接口和枚举上
/** Field declaration (includes enum constants) */
FIELD,//允许作用在属性字段上
/** Method declaration */
METHOD,//允许作用在方法上
/** Formal parameter declaration */
PARAMETER,//允许作用在方法参数上
/** Constructor declaration */
CONSTRUCTOR,//允许作用在构造器上
/** Local variable declaration */
LOCAL_VARIABLE,//允许作用在本地局部变量上
/** Annotation type declaration */
ANNOTATION_TYPE,//允许作用在注解上
/** Package declaration */
PACKAGE,//允许作用在包上
/**
* Type parameter declaration
*
* @since 1.8
*/
TYPE_PARAMETER,//表示该注解能写在类型变量的声明语句中
/**
* Use of a type
*
* @since 1.8
*/
TYPE_USE//表示该注解能写在使用类型的任何语句中(eg:声明语句、泛型和强制转换语句中的类型)
}
内置注解
- @Override
- @Deprecated
- @SuppressWarnings
内置注解之@Override
@Target(ElementType.METHOD)//只能在方法上面使用
@Retention(RetentionPolicy.SOURCE)//只存活在编译期
public @interface Override {
}
它并没有属性值,当然也不能存储任何信息,所以他是一种标记型注解.
仅被编译器可知,编译器在对 java 文件进行编译成字节码的过程中,一旦检测到某个方法上被修饰了该注解,就会去匹对父类中是否具有一个同样方法签名的函数,如果不是,自然不能通过编译.
内置注解之@Deprecated
@Documented//可被保存在joc文档中
@Retention(RetentionPolicy.RUNTIME)//生命周期 : 永久保存
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}
没有属性.也是一种标记性注解
永久存在,可以修饰所有的类型,作用是,标记当前的类或者方法或者字段等已经不再被推荐使用了,可能下一次的 JDK 版本就会删除。
当然,编译器并不会强制要求你做什么,只是告诉你 JDK 已经不再推荐使用当前的方法或者类了,建议你使用某个替代者。
内置注解之@SuppressWarnings
主要用来压制 java 的警告. 例如:启动项目,开始编译时控制台输出的所有警告
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
String[] value();
}
他有一个属性value,可以看到是一个String[].可以根据实际业务取值放入到里面
value值 | 对应的含义 |
---|---|
deprecation | 使用了不赞成使用的类或方法时的警告 |
unchecked | 执行了未检查的转换时的警告,例如当使用集合时没有用泛型 (Generics) 来指定集合保存的类型。 |
fallthrough | 当 Switch 程序块直接通往下一种情况而没有 Break 时的警告。 |
path | 在类路径、源文件路径等中有不存在的路径时的警告。 |
serial | 当在可序列化的类上缺少 serialVersionUID 定义时的警告。 |
finally | 任何 finally 子句不能正常完成时的警告。 |
all | 关于以上所有情况的警告。 |
@SuppressWarnings 批注允许您选择性地取消特定代码段(即,类或方法)中的警告。其中的想法是当您看到警告时,您将调查它,如果您确定它不是问题,您就可以添加一个 @SuppressWarnings 批注,以使您不会再看到警告。虽然它听起来似乎会屏蔽潜在的错误,但实际上它将提高代码安全性,因为它将防止您对警告无动于衷 — 您看到的每一个警告都将值得注意。