(三) 标准注解
.标准注解
Java SE在java.lang, java.lang.annotation和javax.annotation包中定义了大量的注解接口。
其中四个是元注解,用于描述注解接口的行为属性,其他的三个是规则接口,可以用它们来注解源代码中的项。
标准注解 注解接口 应用场合 目的 java.lang Deprecated 全部 将项标记为过时的 SuppressWarnings 除了包和注解之外 阻止某个给定类型的警告信息 Override 方法 检查该方法是否覆盖了某一个类超类方法 javax.annotation PostConstruct 方法 被标记的方法应该在构造之后被调用 PreDestroy 方法 被标记的方法应该在移除之前被调用 Resource 类、接口、方法、属性 在类或接口上:标记为在一个应用程序在运行时将查找的资源 在方法或属性上:容器将把所请求资源的一个实例注入其中 Resources 类、接口 一个资源数组,即此类用于允许多个资源声明 Generated 全部 用于区分单个文件中用户编写的代码和生成的代码。 java.lang.annotation Target 注解 指示注释类型所适用的程序元素的种类 Retention 注解 指示注释类型的注释要保留多久 Documented 注解 指示这个注解应该包含在注解项文档中 Inherited 注解 指示注释类型被自动继承
(1)用于编译的注解
java.lang包下 Deprecated、SuppressWarnings、Override 均为用于编译的注解
@Deprecated 注解可以添加到任何不再鼓励使用的项上。所以,当使用一个已过时的项时,编译器将会发出警告。这个注解与Java文档标签@deprecated具有同等功效。
@SuppressWarnings 注解会告知编译器阻止特殊类型的警告信息
例: @SuppressWarnings("unchecked")
@Override 注解只能应用到方法上,表示一个方法声明打算重写超类中的另一个方法声明。如果方法利用此注解类型进行注解但没有重写超类方法,则编译器会生成一条错误消息。
javax.annotation包下 PostConstruct、PreDestroy、Resource、Resources、Generated
其中 Generated 是用于编译的注解
PostConstruct、PreDestroy、Resource、Resources 是用于管理资源的注解
@Generated 注解的目的是提供代码生产工具来使用。任何生成的源代码都可以被注解,从而与程序员提供的代码区分开。
例如,代码编译器可以隐藏生成的代码,或者代码生成器可以移出生成代码的旧版本。每个注解都必须包含一个表示代码生成器的唯一标识符。日期字符串(ISO8601格式)和说明是可选的。
例:
@Generated(value="com.horstmann.beanproperty", date="2008-01-04T12:05:56.235-0700")
(2)用于管理资源的注解
@PostConstruct和@PreDestroy注解用于控制对象生命周期的环境中,例如Web容器和应用服务器。标记了这些注解的方法应该在对象被构建之后,或者在对象被移除之前调用。
@Resource注解用于资源注入。
例如,考虑访问数据库的Web应用。因为数据库访问信息不应该被硬编码到Web应用中,而是应该让Web容器提供某种用户接口,以便设置连接参数和数据库资源的JNDI名字。
例 在这个Web应用中,可以想下面这样引用数据源:
@Resource(name="jdbc/mydb")
private DataSource source;
(3)元注解
java.lang.annotation包下 Target、Retention、Documented、Inherited 均为元注解
@Target 元注解可以应用于一个注解,以限制该注解可以应用到哪些项上
例 @Target([ElementType.TYPE, Element.METHOD])
public @interface BugReport
下表为所有可能的取值情况,它们属于枚举类型ElementType。可以指定任意数量的元素类型,用括号括起来。
@Target注解的元素类型 元素类型 注解使用场合 ANNOTATION_TYPE 注解类型声明 PACKAGE 包 TYPE 类(包括enum)及接口(包括注解类型) METHOD 方法 CONSTRUCTOR 构造器 FIELD 属性(包括enum常量) PARAMETER 方法或构造器参数 LOCA_VARIABLE 本地变量
一条没有@Target限制的注解可以应用于任何项上。编译器只检查你是否将一条注解应用到某个允许的项上。如果用于错误的项上,则会导致一个编译器错误。
@Retention 元注解用于指定一条注解应该保留多长时间。下表为所有的取值情况,其默认值是 RetentionPolicy.CLASS
用于@Retention注解的保留策略 保留规则 描述 SOURCE 不包括在类文件中的注解 CLASS 类文件中的注解,但是虚拟机不需要将它们载入 RUNTIME 类文件中的注解,并由虚拟机载入。通过反射API可获得它们
@Documented 元注解为像Java东城这样的文档工作提供了一些提示。文档化的注解应该按照其它一些像protected或static这样用于文档目的的修饰符来处理。其他注解的使用不属于文档范畴。
例 将@ActionListenerFor作为一个文档化注解来声明
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ActionListenerFor
现在每一个已注解方法的文档都含有这条注解,所以如果某个注解是暂时的,就不应该对它们的用法进行归档。
注意:将一个注解应用到它自身上是合法的。例如,@Documented注解被它自身注释为@Documented。因此,用于注解的Javadoc文档表明了它们是否可以文档化。
@Inherited 元注解只能应用于对类的注解。如果一个类具有继承注解,那么它的所有子类都自动具有同样地注解。这使得创建一个与Serializable这样的接口修饰符具有同样的运行方式的注解变得很容易。
实际上@Serializable注解应该比没有任何方法的Serializable修饰符接口更恰当。一个类之所以可以被序列化,是因为存在着对它的成员域进行读写的运行期支持,而不是任何面向对象的设计原理。注解比接口继承更擅长描述这一事实。当然,可序列化接口实在JDB 1.1中产生的,比注解出现的早。
例: 假设定义了一个继承注解@Persistent来致命一个类的对象可以存储到数据库中,那么该持久类的子类就会自动被注解为是持久性的。
@Inherited @Persistent{}
@Persistent class Employee {...}
Class Manager extends Empoyee{...} //also @Persistent
在持久性机制取查找存储在数据库中的对象的时候,它就会探测到Employee对象以及Manage对象的存在。