欢迎来到it培训的黄埔军校——智游教育!

java annotation 必须掌握的特性-永利国际

于2017-04-11 11:14:36 发表在java知识库

什么是annotation?

annotation翻译为中文即为注解,意思就是提供除了程序本身逻辑外的额外的数据信息。annotation对于标注的代码没有直接的影响,它不可以直接与标注的代码产生交互,但其他组件可以使用这些信息。
annotation信息可以被编译进class文件,也可以保留在java 虚拟机中,从而在运行时可以获取。甚至对于annotation本身也可以加annotation。


那些对象可以加annotation

类,方法,变量,参数,包都可以加annotation。

内置的annotation

@override 重载父类中方法 @deprecated 被标注的方法或类型已不再推荐使用
@suppresswarnings 阻止编译时的警告信息。其需要接收一个string的数组作为参数。 可供使用的参数有:
· unchecked
· path
· serial
· finally
· fallthrough

可以用与其他annotation上的annotation

@retention
确定annotation被保存的生命周期, 需要接收一个enum对象retentionpolicy作为参数。
public enum retentionpolicy {
    /**
     * annotations are to be discarded by the compiler.
     */
    source,
 
    /**
     * annotations are to be recorded in the class file by the compiler
     * but need not be retained by the vm at run time.  this is the default
     * behavior.
     */
    class,
 
    /**
     * annotations are to be recorded in the class file by the compiler and
     * retained by the vm at run time, so they may be read reflectively.
     *
     * @see java.lang.reflect.annotatedelement
     */
    runtime
}
@documented 文档化
@target
表示该annotation可以修饰的范围,接收一个enum对象enumtype的数组作为参数。
public enum elementtype {
    /** class, interface (including annotation type), or enum declaration */
    type,
 
    /** field declaration (includes enum constants) */
    field,
 
    /** method declaration */
    method,
 
    /** parameter declaration */
    parameter,
 
    /** constructor declaration */
    constructor,
 
    /** local variable declaration */
    local_variable,
 
    /** annotation type declaration */
    annotation_type,
 
    /** package declaration */
    package
}
@inherited
该annotation可以影响到被标注的类的子类。

自定义annotation

jse5.0以后我们可以自定义annotation。下面就是一个简单的例子。
@retention(retentionpolicy.runtime)
@target(elementtype.method)
public @interface methodannotation {
 
}
下面的person对象使用了自定义的methodannotation。
public class person {
 
    public void eat() {
        system.out.println("eating");
    }
 
    @methodannotation
    public void walk() {
        system.out.print("walking");
    }
 
}
我们可以通过反射获取annotation的信息。
 class<person> personclass = person.class;
        method[] methods = personclass.getmethods();
        for(method method : methods){
            if (method.isannotationpresent(methodannotation.class)){
                method.invoke(personclass.newinstance());
            }
        }
输出:
walking
我们也可以给自定义的annotation加方法。
@target(elementtype.type)
public @interface personannotation {
    int id() default 1;
    string name() default "bowen";
}
下面是对personannotation的使用。
@personannotation(id = 8, name = "john")
public class person {
 
    public void eat() {
        system.out.println("eating");
    }
 
    @methodannotation
    public void walk() {
        system.out.print("walking");
    }
 
}

annotation是如何被处理的

当java源代码被编译时,编译器的一个插件annotation处理器则会处理这些annotation。处理器可以产生报告信息,或者创建附加的java源文件或资源。如果annotation本身被加上了rententionpolicy的运行时类,则java编译器则会将annotation的元数据存储到class文件中。然后,java虚拟机或其他的程序可以查找这些元数据并做相应的处理。
当然除了annotation处理器可以处理annotation外,我们也可以使用反射自己来处理annotation。java se 5有一个名为annotatedelement的接口,java的反射对象类class,constructor,field,method以及package都实现了这个接口。这个接口用来表示当前运行在java虚拟机中的被加上了annotation的程序元素。通过这个接口可以使用反射读取annotation。annotatedelement接口可以访问被加上runtime标记的annotation,相应的方法有getannotation,getannotations,isannotationpresent。由于annotation类型被编译和存储在二进制文件中就像class一样,所以可以像查询普通的java对象一样查询这些方法返回的annotation。

annotation的广泛使用

annotation被广泛用于各种框架和库中,下面就列举一些典型的应用.

junit

junit是非常著名的一款单元测试框架,使用junit的时候需要接触大量的annotation。
· @runwith 自定义测试类的runner
· @contextconfiguration 设置spring的applicationcontext
· @dirtiescontext 当执行下一个测试前重新加载applicationcontext.
· @before 调用测试方法前初始化
· @after 调用测试方法后处理
· @test 表明该方法是测试方法
· @ignore 可以加在测试类或测试方法上,忽略运行。
· @beforeclass:在该测试类中的所有测试方法执行前调用,只被调用一次(被标注的方法必须是static)
· @afterclass:在该测试类中的所有的测试方法执行完后调用,只被执行一次(被标注的方法必须是static)

spring

spring 号称配置地狱,annotation也不少。
· @service 给service类加注解
· @repository 给dao类加注解
· @component 给组件类加注解
· @autowired 让spring自动装配bean
· @transactional 配置事物
· @scope 配置对象存活范围
· @controller 给控制器类加注解
· @requestmapping url路径映射
· @pathvariable 将方法参数映射到路径
· @requestparam 将请求参数绑定到方法变量
· @modelattribute 与model绑定
· @sessionattributes 设置到session属性

hibernate

· @entity 修饰entity bean
· @table 将entity类与数据库中的table映射起来
· @column 映射列
· @id 映射id
· @generatedvalue 该字段是自增长的
· @version 版本控制或并发性控制
· @orderby 排序规则
· @lob 大对象标注
hibernate还有大量的关于联合的annotation和继承的annotation,这里就不意义列举了。

jsr 303 – bean validation

jsr 303 – bean validation是一个数据验证的规范,其对java bean的验证主要通过java annotation来实现。
· @null被注释的元素必须为 null
· @notnull被注释的元素必须不为 null
· @asserttrue被注释的元素必须为 [email protected]被注释的元素必须为 [email protected](value)被注释的元素必须是一个数字,其值必须大于等于指定的最小值
· @max(value)被注释的元素必须是一个数字,其值必须小于等于指定的最大值
· @decimalmin(value)被注释的元素必须是一个数字,其值必须大于等于指定的最小值
· @decimalmax(value)被注释的元素必须是一个数字,其值必须小于等于指定的最大值
· @size(max, min)被注释的元素的大小必须在指定的范围内
· @digits (integer, fraction)被注释的元素必须是一个数字,其值必须在可接受的范围内
· @past被注释的元素必须是一个过去的日期
· @future被注释的元素必须是一个将来的日期
· @pattern(value)被注释的元素必须符合指定的正则表达式
其实还有很多使用了annotaion的framework或library,这里就不一一列举了,希望大家能举一反三,深入了解java中的annotation。