本文已参与「新人创作礼」活动,一起开启掘金创作之路。
前言
Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。注解就像一个标签,类、方法、变量、参数和包等都可以被标注,还支持标记注解的注解。被标注的对象在特定时候会被处理。
内置注解
Java内置了7个注解,3个在java.lang、4个在java.lang.Annotation,其中前三个是修饰代码的直接,后四个是修饰注解的注解,又被称为“元注解”
首先分析元注解,元注解是声明其他注解的重要部分
元注解
元注解是修饰注解的注解,主要是帮助定义一个注解,有四个元注解
- @Retention:定义注注解怎么保存
- @Documented:被修饰的注解会生成到javadoc中
- @Target:定义注解的适用对象
- @Inherited:被修饰的注解修饰的类的子类也会拥有该被修饰的注解(类似继承但不是继承)
@Retention
注解的保存有三种方式
- SOURCE:被编译器忽略
- CLASS:(默认)编入class文件
- RUNTIME:编入class文件并且在运行时能够通过反射获取
@Documented
被修饰的注解会显示在javadoc中,javadoc生成使用javadoc xxx.java
@Target
@Target定义该注解能标记的元素,如果要定义支持多种元素,使用枚举类的花括号声明,默认为全体元素
package java.lang.annotation;
public enum ElementType {
/** 类、接口、枚举类 */
TYPE,
/** 变量声明,包括枚举 */
FIELD,
/** 方法声明 */
METHOD,
/** 参数声明 */
PARAMETER,
/** 构造器声明 */
CONSTRUCTOR,
/** 局部变量声明 */
LOCAL_VARIABLE,
/** 元注解声明 */
ANNOTATION_TYPE,
/** 包声明 */
PACKAGE,
/**
* Type parameter declaration
* 参数类型声明
* @since 1.8
*/
TYPE_PARAMETER,
/**
* Use of a type
* 类型使用
* @since 1.8
*/
TYPE_USE
}
@Inherited
@Inherited修饰一个注解,拥有这个注解的类的子类也拥有这个注解,这里不是extends继承关系,注解不支持继承
首先定义一个注解
然后修饰一个类,子类继承该类,输出注解
修饰代码的注解
- @Override:检查该方法是否是重写方法,如果父类、接口没有该方法就报编译错误。
- @Deprecated:标记为过时的方法,如果被调用抛警告
- @SuppressWarnings:声明一个警告类型,会忽略该警告
@Override
只能修饰方法,在编译的时候就会被丢弃,因此该注解不写也可以但是不符合规范。
一个方法被标记,就说明是重写了父类、接口的同名方法,如果父类没有该方法就会报错,相当于检测重写的方法是否正确、有没有正确重写。
@Deprecated
可以修饰很多元素:构造器、局部变量、方法、包、参数、类、接口
被@Deprecated标记的元素已经被弃用,如果强行调用会抛出警告,而该方法仍旧会正常运行。idea会在调用被标记的方法时添加一个删除线作为标记。
@SuppressWarnings
可以修饰很多元素,在编译时被丢弃
被标注的方法运行时遇到声明的警告就不会提示,声明的警告通过value赋值@SupressWarning(value="XXX")。
警告关键字参照下表:
还是借用上面的例子,让main忽略deprecation警告,删除线也自动消失了
Java7+新注解
- @SafeVarargs - Java 7 ,忽略任何使用参数为泛型变量的方法或构造函数调用产生的警告。
- @FunctionalInterface - Java 8 ,标识一个匿名函数或函数式接口。
- @Repeatable - Java 8,标识某注解可以在同一个声明上使用多次。
自定义注解
自定义注解如同定义接口,使用的是@interface
根据需要添加元注解
注解使用场景
最典型的场景就是JUnit,将被测试方法打上注解,在测试过程中根据注解读取、测试