java annotation 必须掌握的特性-mile米乐体育
什么是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的信息。
classpersonclass = 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被注释的元素必须为 true@assertfalse被注释的元素必须为 false@min(value)被注释的元素必须是一个数字,其值必须大于等于指定的最小值
- @max(value)被注释的元素必须是一个数字,其值必须小于等于指定的最大值
- @decimalmin(value)被注释的元素必须是一个数字,其值必须大于等于指定的最小值
- @decimalmax(value)被注释的元素必须是一个数字,其值必须小于等于指定的最大值
- @size(max, min)被注释的元素的大小必须在指定的范围内
- @digits (integer, fraction)被注释的元素必须是一个数字,其值必须在可接受的范围内
- @past被注释的元素必须是一个过去的日期
- @future被注释的元素必须是一个将来的日期
- @pattern(value)被注释的元素必须符合指定的正则表达式
其实还有很多使用了annotaion的framework或library,这里就不一一列举了,希望大家能举一反三,深入了解java中的annotation。