6. Java语言内置的Annotation简介
6.1 基本内置类型
在Java 1.5 之后,引入了三个基本的Annotation类型,分别为: @Override,@Deprecated, @SuppressWarnings.
java.lang.Override,作用于方法级别,只存在与编译阶段使用,由于其定义涵盖@Target(value=METHOD), @Retention(value=SOURCE)。
其为Marker Annotation, 仅用作标识方法,表示其重载了父类的方法;如果使用了@Override,实际上却并未覆盖父类方法,java编译器将提示一个编译错误。我们其实,可以将其理解为一个强化语法检查的断言,辅助开发者减少错误。
2. @Deprecated标识Annotation,作用于方法各个级别的代码,在运行阶段使用。
在使用@Deprecated修饰的方法、变量等之后,编译器将不鼓励使用这个被标注的程序元素。使用这种修饰可以扩散到子类中,例如在代码中通过继承或者覆盖的方式使用了这个@Deprecated标识的类型或者成员,即使继承或者覆盖后的类型或者成员并不是被声明为 @Deprecated,但编译器仍然要抛出警告信息。
@SuppressWarnings(value={"unchecked","fallthrough"})
public void suppressedMethod() {
//Logic Code
}
这里仅仅列出了两种需要屏蔽的警告类型,如需查看所有可能的警告信息类型,可以查看参考资料4.
6.2 Meta-Annotation
主要功能是用以修饰Annotation,简而言之,就是用以创建新的Annotation的修饰Annotation。虽然有点绕口,Meta-Annotation就明确地表明他的位置。先看一个例子吧:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
ElementType[] value();
}
这个是Target在JDK源码中的定义,通过这个例子充分说明了Meta-Annotation的用法。 这里比较有意思的是,@Target在源码中是通过自我定义来完成的,就是@Target本身是使用@Target来修饰和定义的。
这个例子中@Documented标识其会在javadoc中出现,@Retention标识其在代码运行中使用,@Target标识其仅用作Annotation类型。
接下来,我们将分别对这些Meta-Annotation做详细讲解。
限定Annotation所修饰的对象范围,范围包括packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。在Annotation类型的声明中使用了target可更加明晰其修饰的目标,一句话,这个Annotation可以用在什么地方。
可用的取值(ElementType)有:
2. @Rentention
定义了该Annotation被保留的时间长短,或者说生命周期,即其会在哪个阶段被保留,并在哪个阶段会被使用到。
其value的取值(RetentionPoicy)有:
出现在源代码中,而被编译器丢弃。
被编译在class文件中;编译在class文件中的Annotation可能会被虚拟机忽略。
其被编译到class中,并在运行时,被读取和使用的。
3. @Documented
描述其它类型的annotation被作为被标注的程序成员的公共API,从而被javadoc此类的工具文档化。标记注解,没有成员。
4. @Inherited
标记注解,标识某个被标注的类型是被继承的。使用了@Inherited修饰的annotation类型被用于一个class之时,,则这个annotation将被用于该class的相应子类。
注意:@Inherited annotation类型是被标注过的class的子类所继承。类并不从它所实现的接口继承annotation,方法并不从它所重载的方法继承annotation。
当@Inherited annotation类型标注的annotation的Retention是RetentionPolicy.RUNTIME,则反射API增强了这种继承性。如果我们使用java.lang.reflect去查询一个@Inherited annotation类型的annotation时,反射代码检查将展开工作:检查class和其父类,直到发现指定的annotation类型被发现,或者到达类继承结构的顶层。
就是说, 查看查找@Inherited过的Annotation之时,需要反复的向上查找,方才可以。
下面以Spring中@Controller的定义为样例来看看它们的使用:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
}
限于篇幅,这里就不再针对@Inherited做示例讲解了,大家如果感兴趣的话,可以查看以下链接中的示例,就一目了然了。
范例讲解: http://www.jroller.com/alessiopace/entry/annotation_inheritance_examples
总结: 在本节中,我们着重讲解了Java语言中内置的Annotation和Meta-Annotation。