1. 简介
注解(Annotation)相当于代码里的特殊标记,使被修饰的元素在编译、加载、运行时读取信息并进行处理。可看作是对一个 类/方法 的一个扩展的模版,每个 类/方法 按照注解类中的规则,来为 类/方法 注解不同的参数,在用到的地方可以得到不同的 类/方法 中注解的各种参数与值。
2. JDK内置注解
2.1 @Override
限定子类重写父类的方法,或者接口实现类实现接口的方法。该注解只能修饰方法。
2.2 @Deprecated
用于表示修饰的元素(类、方法等)已过时,一般会有更好的选择。当仍要使用这些类或方法时,会有一条划线。
2.3 @SuppressWarnings
用于抑制编译器的警告。例子如下:
// 不加注解会有如下警告Class 'Person' is never used
@SuppressWarnings("unused")
public class Person {
}
2.4 @SafeVarargs
Java 7 引入,用于抑制堆污染的警告。例子如下:
@SafeVarargs // 不加注解会有如下警告Type safety: Potential heap pollution via varargs parameter infos
public static <T> void test(T... infos) {
for (T info : infos) {
System.out.println(info);
}
}
使用这个注解的两个条件:
1.只能用在参数长度可变的方法上
2.方法必须是static或final修饰的
关于该注解的更多内容可参考这篇文章。
2.5 @FunctionalInterface
Java 8引入,声明某个接口是一个函数式接口,即这种接口只有一个抽象方法。函数式接口的实例对象可以用lambda表达式来创建。
3. 元注解
元注解可以理解成用来修饰注解的特殊注解。
3.1 @Retention
声明被修饰注解的生命周期,其取值如下:
| 取值 | 解释 |
|---|---|
| RetentionPolicy.SOURCE | 被修饰注解只在源文件有效,编译器会丢弃该注解 |
| RetentionPolicy.CLASS | (默认值)被修饰注解会记录在class文件中,程序运行时,JVM不能获取注解信息。 |
| RetenionPolicy.RUNTIME | 被修饰注解会记录在class文件中,程序运行时,JVM可以通过反射获取注解信息。 |
3.2 @Target
声明被修饰注解的作用范围,其取值如下:
| 取值 | 解释 |
|---|---|
| ElementType.TYPE | 可用于类、接口、枚举类 |
| ElementType.FIELD | 可用于属性字段 |
| ElementType.METHOD | 可用于方法 |
| ElementType.PARAMETER | 可用于方法的参数 |
| ElementType.CONSTRUCTOR | 可用于构造器 |
| ElementType.LOCAL_VARIABLE | 可用于局部变量 |
| ElementType.ANNOTATION_TYPE | 可用于注解上,即@interface类上 |
| ElementType.PACKAGE | 可用于包上,用于记录java文件的包信息 |
| ElementType.TYPE_PARAMETER | Java 8 引入,可用于类型变量的声明语句中,如泛型声明 |
| ElementType.TYPE_USE | Java 8 引入,可用于使用类型的任何语句中 |
3.3 @Documented
被修饰的注解被javadoc解析时,会保留下来。
3.4 @Inherited
被修饰的注解具有继承性。比如某个类使用了被@Inherited修饰的注解,那么这个类的子类也会具有该注解。
3.5 @Repeatable
Java 8 引入,声明可重复注解。
3.5.1 Java 8 前的写法
1、创建一个自定义注解MyAnnotation
public @interface MyAnnotation {
String value();
}
2、创建一个新注解,其字段为MyAnnotation的数组
public @interface MyNewAnnotation {
MyAnnotation[] value();
}
3、使用注解
@MyNewAnnotation(value = {@MyAnnotation(value = "hello1"), @MyAnnotation(value = "hello2")})
public class Demo01 {
}
3.5.2 Java 8 写法
1、在注解MyAnnotation上使用元注解@Repeatable,值为MyNewAnnotation.class
@Repeatable(MyNewAnnotation.class)
public @interface MyAnnotation {
String value();
}
2、使用重复注解
@MyAnnotation(value = "hello1")
@MyAnnotation(value = "hello2")
public class Demo01 {
}
(注:两个注解@MyAnnotation、@MyNewAnnotation的Target和Retention要相同;且同时要都有或都没有Inherited)