优雅写Java注解

来源:互联网 发布:网络采购员 编辑:程序博客网 时间:2024/05/16 10:49
作者:郭无心
链接:https://www.zhihu.com/question/36486629/answer/70598262
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

优雅的使用Java注解的前提是理解Java注解,并学习优秀的Java注解的使用demo。

注解作用:每当你创建描述符性质的类或者接口时,一旦其中包含重复性的工作,就可以考虑使用注解来简化与自动化该过程。

Java提供了四种元注解,专门负责新注解的创建工作。


比如Junit3和Junit4 ,比如Servlet2与Servlet3 比如Hibernate3与Hibernate4 比如Spring2之后的Spring版本,都引用注解这一机制,作用就是利用注解将一些本来重复性的工作,变成程序自动完成,简化和自动化该过程(PostScript:上述各个组件我也不是很熟悉,具体加入注解的版本是几不一定正确)。


元注解的作用就是负责注解其他注解。Java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其它 annotation类型作说明。Java5.0定义的元注解:

    1.@Target,    2.@Retention,    3.@Documented,    4.@Inherited


  这些类型和它们所支持的类在java.lang.annotation包中可以找到。下面我们看一下每个元注解的作用和相应分参数的使用说明。


@Target

@Target说明了Annotation所修饰的对象范围:Annotation可被用于 packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。在Annotation类型的声明中使用了target可更加明晰其修饰的目标。

作用:用于描述注解的使用范围(即:被描述的注解可以用在什么地方)

 取值(ElementType)有:

 1.CONSTRUCTOR:用于描述构造器 2.FIELD:用于描述域 3.LOCAL_VARIABLE:用于描述局部变量 4.METHOD:用于描述方法 5.PACKAGE:用于描述包 6.PARAMETER:用于描述参数 7.TYPE:用于描述类、接口(包括注解类型) 或enum声明
例子:
Entity.java
/*** * * 实体注解接口 */@Target(value = {ElementType.TYPE}) //仅应用于类、接口、enum声明、注解类型@Retention(value = RetentionPolicy.RUNTIME) //运行时有效public @interface Entity {    /***     * 实体默认firstLevelCache属性为false     * @return boolean     */    boolean firstLevelCache() default false;    /***     * 实体默认secondLevelCache属性为false     * @return boolean     */    boolean secondLevelCache() default true;    /***     * 表名默认为空     * @return String     */    String tableName() default "";    /***     * 默认以""分割注解     */    String split() default "";}

@Retention

 @Retention定义了该Annotation被保留的时间长短:某些Annotation仅出现在源代码中,而被编译器丢弃;而另一些却被编译在class文件中;编译在class文件中的Annotation可能会被虚拟机忽略,而另一些在class被装载时将被读取(请注意并不影响class的执行,因为Annotation与class在使用上是被分离的)。使用这个meta-Annotation可以对 Annotation的“生命周期”限制。

作用:表示需要在什么级别保存该注释信息,用于描述注解的生命周期(即:被描述的注解在什么范围内有效)

 取值(RetentionPoicy)有:

    1.SOURCE:在源文件中有效(即源文件保留)
    2.CLASS:在class文件中有效(即class保留)
    3.RUNTIME:在运行时有效(即运行时保留)

/*** * 字段注解接口 */@Target(value = {ElementType.FIELD})//注解可以被添加在属性上@Retention(value = RetentionPolicy.RUNTIME)//注解保存在JVM运行时刻,能够在运行时刻通过反射API来获取到注解的信息public @interface Column {    String name();//注解的name属性}





-------------------------------------分割线---------------------------------------------------------
一个完整的例子

注解:DBTable.java
package annotations.database;import java.lang.annotation.*;@Target(ElementType.TYPE) // 应用于类、接口、enum、注解类型@Retention(RetentionPolicy.RUNTIME)public @interface DBTable {  public String name() default "";} 

注解:Constraints.java
package annotations.database;import java.lang.annotation.*;@Target(ElementType.FIELD) //用于变量名@Retention(RetentionPolicy.RUNTIME)public @interface Constraints {  boolean primaryKey() default false;  boolean allowNull() default true;  boolean unique() default false;} 
注解:SQLString.java
package annotations.database;import java.lang.annotation.*;@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface SQLString {  int value() default 0;  String name() default "";  Constraints constraints() default @Constraints;} 

注解:SQLInteger.java
package annotations.database;import java.lang.annotation.*;@Target(ElementType.FIELD)//FIELD  用于变量名@Retention(RetentionPolicy.RUNTIME)public @interface SQLInteger {  String name() default "";  Constraints constraints() default @Constraints;} 


类Member.java
package annotations.database;@DBTable(name = "MEMBER")public class Member {  @SQLString(30) String firstName;  @SQLString(50) String lastName;  @SQLInteger Integer age;  @SQLString(value = 30,constraints = @Constraints(primaryKey = true))  String handle;    static int memberCount;  public String getHandle() { return handle; }  public String getFirstName() { return firstName; }  public String getLastName() { return lastName; }  public String toString() { return handle; }  public Integer getAge() { return age; }}
------------------------------分割线-----------------------------------
阅读全文
0 0