1 注解数据
注解是插入到源代码中,用于工具处理的标签。在JDK5之前,注解只用来描述代码,而现在可以利用工具将任务数据插入到现有的源代码中。

2 注解语法
自定义注解,由接口来实现的;自定义的注解类都隐含的继承自Java.lang.annotation.Annotation接口,这是一个普通接口。
modifiers @interface AnnotName
{
    type element1() [ default value ];
    type element2() [ default value ];
}
类型只能为以下几种类型:基本类型如int等,String,Class类,enum类型,注解类型(嵌套),由前面类型组成的一维数组。
由于注解是由编译器计算而来的,因此所有的元素必须是编译期常量。

注解在定义之后,使用时的形式如下:
@AnnotName(element1=val1,element2={val2,val3}...)
元素的顺序没有限制,如果某个元素没有指定,则使用声明的默认值;
注解元素不能使用null值,只能使用""或Void.class。
如果元素的值是数组,则使用{}括起来。

如果使用的注解不包含元素,或者元素都使用默认值,则注解可以简化为@Annotation,可以去掉括号后的内容。
如果注解只包含一个元素,并且元素名称为value(),我们在使用的时候可以去掉赋值的形式,@Annotation(val)。

注解可以应用到的项有包、类、接口、方法、构造器、实例成员、本地变量、参数变量上。一个项可以被多个注解说明,但同一类型的注解不能使用多次。如果要使用多次,需要定义一个包含多个注解的注解。

java.lang.annotation.Annotation接口
Class<? extends Annotation> annotationType() 返回注解的元类

java.lang.reflect.AnnotatedElement类
<T extends Annotation> getAnnotation(Class<T> aclass)  如果项存在指定类型的注解,则返回,否则返回
Annotation[] getAnnotations()  返回所有的注解,包含继承的
Annotation[] getDeclaredAnnotations() 返回此条目所声明的注解
bool isAnnotationPresent(Class<? extends Annotation> aclass) 是否存在给定类型的注解

3 标准注释
JDK6起定义的注解有如下几个,javax包里有更多的注解,不在此解释。

3.1 编译项注解
@Deprecated  表示不鼓励使用的项,当使用时编译器会产生警告。
@SuppressWarnings 告诉编译器不对特定类型问题进行警告,如@suppressWarnings("unchecked")
@Override 告诉编译器本方法是重写的方法。当然在一个不允许重载的方法上使用,则产生错误。
3.2 资源注解
对于对象,可以控制对象的生命期。对于方法,可以控制期执行时刻。
@PostConstruct 
@PreDestroy
@Resource 用于替换注入,在JRE7中好像没找到
3.3 元注解
用于说明注解的注解。
@Target 用于说明注解的适用类型,如ElementType.METHOD,没有Target注解的项可以用于任意类型。

@Retention 用于说明注解的存在范围,默认值为RetentionPolicy.CLASS。

@Document 用于让文档工具进行信息抽取生成此注解标记项的文档
@Inherit 用于让此注解可以同时让子类继承

4 源码级别的注解处理器
在JDK5时,需要使用外部apt工具来处理带有注解的类,在jdk6中已经可以直接使用javac来处理注解了。
对于用于处理源码级的注解的方法是继承自AnnotationProcess类,并实现process方法,假设我们实现的类名是proAnno.java,编译此类。然后写一个使用注解类。
javac -processor proAnno classWithAnno.java

5 运行时注解
需要在运行时使用反射机制获取注解的数据,并进行处理。例如将一系列类,在运行时注册到某个集合中。
为此反射类中增加了获取条目上的注解的API。Junit便采用注解的方式来声明测试用例。
下面的示例采用注解的方式增加了一种运行时权限控制。



6 字节码工程
通过注解可以处理编译的字节码,并插入自己的代码。这已经属于比较高级的hack行为,暂时不在此描述。

7 用途
使用注解标记字段和方法,可通过反射的手段截取注解及其标记的字段和方法的元数据,并根据需求对元数据进行处理。
它赋予了字段和方法额外的意义,提供了一种统一处理字段和方法的优雅的方式。
注解更多的意义是提供了一种设计模式,在本质上它没有增强Java的能力,使用注解实现的功能都可以以非注解的方式实现,只是通过注解可以让代码看起来更加显示描述性一些。




Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐