Annotation注解类
本文结构:
1. 概念
Java Annotation是JDK5.0引入的一种注释机制。
关于Annotation注解的概念,我们可以先看下官方的解释:
Annotations, a form of metadata;
provide data about a program that is not part of the program itself.
Annotations have no direct effect on the operation of the code they annotate
Annotation注解是Java中的一种元数据,它可以往程序中添加额外的数据,并且对注解的代码无直接的影响。注解是一种接口,可以作用于包名、类、方法、属性、参数等。它可以通过反射机制来访问annotation信息,获得所加的注解信息。
2. Java.lang中的注解
Java.lang中的注解又称为标准Annotation,即常用到的Deprecated、Override和SuppressWarnings。
(1)@Deprecated 过时:表示该方法已过时,建议使用新的一些方法代替。
(2)@Override 复写:表示复写父类的方法,如果方法上有这条注解但没有重写父类方法,则会生成一条错误信息。这个注解保证了方法一定会被复写。比如在开发过程中,手动在子类中复写父类的方法,只正确写出了方法名称,未写出正确的方法参数,则相当于方法的重载,并不是复写。所以使用@Override注解,有效地表明,此方法是复写父类的方法,不会产生手动的错误问题。
(3)@SuppressWarnings 阻止警告,阻止弹出的警告,比如加上此注解可屏蔽上述过时的警告。
3. 元注解
元注解是指注解Annotation的注解。以Override的源代码为例:
1 | (ElementType.METHOD) |
注解类的定义方法以及注解类上所加的注解。元注解有四个,位于java.lang.annotation包中:Target,Retention,Documented、Inherited。
3.1 @Target 表示注解作用的目标。
1 |
|
注解作用的目标由枚举类ElementType决定。
1 | public enum ElementType{ |
注:Class,interface等都实现了java中的Type接口,因此ElementType.TYPE表示注解作用于这些“类”(并不是单纯的Class类)
3.2 @Retention 表示注解的作用时段
1 |
|
由源码可见,Retention定义的是RetentionPolicy类型的数据1
2
3
4
5public enum RetentionPolicy{
SOURCE,//表示注解只在源文件中保留
CLASS,//表示注解保留到.class文件中
RUNTIME,//表示注解一直保留到内存中,类加载器把.class文件加载到内存中产生的字节码中要保留注解信息
}
3.3 @Documented 表示javadoc所生成的文档会带上注解信息。
3.4 @Inherited 表示子类可以集成加载父类上的注解,但要注意:(1)注解定义在类上面,子类可以继承该注解;(2)注解定义在方法上,子类也可继承该注解;但是如果子类复写了父类中定义了注解的方法,子类将无法继承该方法上的注解;(3)Interface的实现类无法继承接口中所定义的被@Inherited标注的注解
4. 注解的参数
参数类型支持基本数据类型、Class类型、enum类型、Annotation类型以及上述所有类型的数组。
5. 自定义注解
步骤:
- 使用@interface定义一个注解类(其内部自行继承了Annotation类)
- 在该类中定义注解的参数(类似定义方法)
- 注解元素必须由确定的值,可在定义注解的默认值中指定,也可在使用注解时指定(非基本类型的注解元素的值不可为null)
example:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
(ElementType.TYPE)
(RetentionPolicy.RUNTIME)
public Car{
String name() default "";
int number() default -1;
}
"宝马", number = 666) (name =
public class CarBWM{
public static void main(String[] args){
//判断CarBMW是否有注解类Car
if(CarBMW.class.isAnnotationPresent(Car.class)){
Car carAnnotation = (Car)CarBMW.class.getAnnotation(Car.class);
System.out.println("car name " + carAnnotation.name());
System.out.println("car number " + carAnnotation.number());
}
}
}