解析注解Annotation

来源:互联网 发布:编程语言 难度 编辑:程序博客网 时间:2024/09/21 09:28

注解(元数据)在我们代码中提供形式化的方法,注解是跟你的源代码结合在一起使用的.注解之所以产生,是为了减少样板试代码的开发,提供开发效率.

注解相对比较简单的,除了使用@符号,基本与java固有的的语法是一致的。

java.lang.的有三种标准的注解:

@Override:

@Deprecated:

@SuppressWarnings:

四种元注解:负责创建其他注解

@Target

@Retention

@Document

@Inherited


定义注解

package com.anno;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface UseCase {public abstract int id() default 0;public abstract String value() default "";}

       @Target(ElementType.METHOD): 你的注解应用于什么地方,ElementType提供了8中方式 

               /** 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

      @Retention(RetentionPolicy.RUNTIME):你的注解在哪个级别二用,在源码(Source),类文件中(Class)或者是在运行时(RUNTIME)

应用注解  

package com.anno;public class Utils {@UseCase(id = 0, value = "1")public boolean validate() {return false;}@UseCase(id = 1, value = "2")public boolean validate1() {return false;}@UseCase(id = 2, value = "3")public boolean validate2() {return false;}}

如果没有注解读取工具,那注解也不会比注释更有用.使用注解过程中,最重要的编写注解处理器,Java API 反射机制扩展了注解,同时提供了外部工具apt解析带有注解的源码.

下面是非常简单的注解解析器帮助我们解析Utils

package com.anno;import java.lang.reflect.Method;public class AnnoUtils {public static void parse(Class<?> cls) {Method[] methods = cls.getDeclaredMethods();for (Method e : methods) {UseCase useCase = e.getAnnotation(UseCase.class);System.out.println("Method Name:" + e.getName() + " Annocation Id:" + useCase.id() + " Anocation value" + useCase.value());}}public static void main(String[] args) {AnnoUtils.parse(Utils.class);}}

Method Name:validate Annocation Id:0 Anocation value1Method Name:validate1 Annocation Id:1 Anocation value2Method Name:validate2 Annocation Id:2 Anocation value3
注解的元素:
注解元素可用的类型如下:
  • 所有的基础数据类型(int\float\double\boolean\char\long\short\byte)
  • String
  • Class
  • Annocation
  • enum
  • 以上类型的数组

编译器对元素的过分的限制,首先元素不能有不确定的值,也就是说元素不然又默认值,不然使用注解的时候必须指定.并且非基本数据类型不能为NULL,为了绕开这个约束,我们定义一些特殊的值,比如负数或者空字符串,此意表示元素不存在

public @interface UseCase {public abstract int id() default -1;public abstract String value() default "";}
高级应用

假如你希望提供一些基础的对象/关系数据库映射,

  • 定义映射表的注解
package com.anno;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @interface Table {public abstract String value();}
  • 定义公共属性
package com.anno;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface Constraines {public abstract boolean primarkKey() default false;public abstract boolean allowNull() default true;public abstract boolean unique() default false;}
package com.anno;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;public interface R {@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)@interface SQLString {public abstract String column() default "";public abstract String value() default "";public abstract Constraines constraines() default @Constraines;}@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)@interface SQLInteger {public abstract String column() default "";public abstract int value() default -1;public abstract Constraines constraines() default @Constraines;}@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)@interface SQLDate {public abstract String column() default "";public abstract long value() default -1;public abstract Constraines constraines() default @Constraines;}}

下面定义个简单的JavaBean:

package com.anno;import com.anno.R.SQLInteger;import com.anno.R.SQLString;@Table(value = "TBL_CIF")public class Memery {@SQLInteger(constraines = @Constraines(allowNull = false, primarkKey = true, unique = true))private int id;@SQLString(constraines = @Constraines(allowNull = false, primarkKey = true, unique = true))private String fristName;@SQLString(constraines = @Constraines(allowNull = false, primarkKey = true, unique = true))private String lastName;}

接口R中我对注解统一管理,在对不同类型实施注解时,出现了重复的代码,Constraines constraines() default @Constraines;是不是可以通过集成@interface呢?这样可以减少大量的代码,很遗憾注解不支持Extend.以上代码也是最优的了大笑











  

     

       

  

     

      











0 0
原创粉丝点击