java自定义注解和运行时靠反射机制获取注解

java自定义注解:java注解是附加在代码上的一些元信息,用于一些工具在编译,运行时进行解析和使用,起到说明配置的功能。注解不会也不能影响代码的实际逻辑,只起到辅助的作用,包含在java.lang.annotation中。

元注解:指注解的注解。包括@Retetion @Target @Ducument&@Inherited.


1.1、@Retention: 定义注解的保留策略

@Retention(RetentionPolicy.SOURCE)    //注解仅存在于源码中,在class字节码文件中不包含
@Retention(RetentionPolicy.CLASS)       // 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得,
@Retention(RetentionPolicy.RUNTIME)   // 注解会在class字节码文件中存在,在运行时可以通过反射获取到

注解类:
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. @Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,在运行时可以通过反射获取到  
  2. @Target({ElementType.FIELD,ElementType.METHOD})//定义注解的作用目标**作用范围字段、枚举的常量/方法  
  3. @Documented//说明该注解将被包含在javadoc中  
  4. public @interface FieldMeta {  
  5.   
  6.     /** 
  7.      * 是否为序列号 
  8.      * @return 
  9.      */  
  10.     boolean id() default false;  
  11.     /** 
  12.      * 字段名称 
  13.      * @return 
  14.      */  
  15.     String name() default "";  
  16.     /** 
  17.      * 是否可编辑 
  18.      * @return 
  19.      */  
  20.     boolean editable() default true;  
  21.     /** 
  22.      * 是否在列表中显示 
  23.      * @return 
  24.      */  
  25.     boolean summary() default true;  
  26.     /** 
  27.      * 字段描述 
  28.      * @return 
  29.      */  
  30.     String description() default "";  
  31.     /** 
  32.      * 排序字段 
  33.      * @return 
  34.      */  
  35.     int order() default 0;  
  36. }  

实体类:
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public class Anno {  
  2.   
  3.     @FieldMeta(id=true,name="序列号",order=1)  
  4.     private int id;  
  5.     @FieldMeta(name="姓名",order=3)  
  6.     private String name;  
  7.     @FieldMeta(name="年龄",order=2)  
  8.     private int age;  
  9.       
  10.     @FieldMeta(description="描述",order=4)  
  11.     public String desc(){  
  12.         return "java反射获取annotation的测试";  
  13.     }  
  14.       
  15.     public int getId() {  
  16.         return id;  
  17.     }  
  18.     public void setId(int id) {  
  19.         this.id = id;  
  20.     }  
  21.     public String getName() {  
  22.         return name;  
  23.     }  
  24.     public void setName(String name) {  
  25.         this.name = name;  
  26.     }  
  27.     public int getAge() {  
  28.         return age;  
  29.     }  
  30.     public void setAge(int age) {  
  31.         this.age = age;  
  32.     }  
  33.       
  34. }  

获取到注解的帮助类:
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public class SortableField {  
  2.   
  3.     public SortableField(){}  
  4.       
  5.     public SortableField(FieldMeta meta, Field field) {  
  6.         super();  
  7.         this.meta = meta;  
  8.         this.field = field;  
  9.         this.name=field.getName();  
  10.         this.type=field.getType();  
  11.     }  
  12.       
  13.       
  14.     public SortableField(FieldMeta meta, String name, Class<?> type) {  
  15.         super();  
  16.         this.meta = meta;  
  17.         this.name = name;  
  18.         this.type = type;  
  19.     }  
  20.   
  21.   
  22.     private FieldMeta meta;  
  23.     private Field field;  
  24.     private String name;  
  25.     private Class<?> type;  
  26.       
  27.     public FieldMeta getMeta() {  
  28.         return meta;  
  29.     }  
  30.     public void setMeta(FieldMeta meta) {  
  31.         this.meta = meta;  
  32.     }  
  33.     public Field getField() {  
  34.         return field;  
  35.     }  
  36.     public void setField(Field field) {  
  37.         this.field = field;  
  38.     }  
  39.     public String getName() {  
  40.         return name;  
  41.     }  
  42.     public void setName(String name) {  
  43.         this.name = name;  
  44.     }  
  45.   
  46.     public Class<?> getType() {  
  47.         return type;  
  48.     }  
  49.   
  50.     public void setType(Class<?> type) {  
  51.         this.type = type;  
  52.     }  
  53.       
  54.       
  55. }  

运行时获取注解,首先创建一个基类:
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public class Parent<T> {  
  2.   
  3.     private Class<T> entity;  
  4.   
  5.     public Parent() {  
  6.         init();  
  7.     }  
  8.   
  9.     @SuppressWarnings("unchecked")  
  10.     public List<SortableField> init(){  
  11.         List<SortableField> list = new ArrayList<SortableField>();  
  12.         /**getClass().getGenericSuperclass()返回表示此 Class 所表示的实体(类、接口、基本类型或 void) 
  13.          * 的直接超类的 Type(Class<T>泛型中的类型),然后将其转换ParameterizedType。。 
  14.          *  getActualTypeArguments()返回表示此类型实际类型参数的 Type 对象的数组。 
  15.          *  [0]就是这个数组中第一个了。。 
  16.          *  简而言之就是获得超类的泛型参数的实际类型。。*/  
  17.         entity = (Class<T>)((ParameterizedType)this.getClass().getGenericSuperclass())  
  18.                 .getActualTypeArguments()[0];  
  19. //      FieldMeta filed = entity.getAnnotation(FieldMeta.class);  
  20.           
  21.         if(this.entity!=null){  
  22.               
  23.             /**返回类中所有字段,包括公共、保护、默认(包)访问和私有字段,但不包括继承的字段 
  24.              * entity.getFields();只返回对象所表示的类或接口的所有可访问公共字段 
  25.              * 在class中getDeclared**()方法返回的都是所有访问权限的字段、方法等; 
  26.              * 可看API 
  27.              * */  
  28.             Field[] fields = entity.getDeclaredFields();  
  29. //            
  30.             for(Field f : fields){  
  31.                 //获取字段中包含fieldMeta的注解  
  32.                 FieldMeta meta = f.getAnnotation(FieldMeta.class);  
  33.                 if(meta!=null){  
  34.                     SortableField sf = new SortableField(meta, f);  
  35.                     list.add(sf);  
  36.                 }  
  37.             }  
  38.               
  39.             //返回对象所表示的类或接口的所有可访问公共方法  
  40.             Method[] methods = entity.getMethods();  
  41.               
  42.             for(Method m:methods){  
  43.                 FieldMeta meta = m.getAnnotation(FieldMeta.class);  
  44.                 if(meta!=null){  
  45.                     SortableField sf = new SortableField(meta,m.getName(),m.getReturnType());  
  46.                     list.add(sf);  
  47.                 }  
  48.             }  
  49.             //这种方法是新建FieldSortCom类实现Comparator接口,来重写compare方法实现排序  
  50. //          Collections.sort(list, new FieldSortCom());  
  51.             Collections.sort(list, new Comparator<SortableField>() {  
  52.                 @Override  
  53.                 public int compare(SortableField s1,SortableField s2) {  
  54.                     return s1.getMeta().order()-s2.getMeta().order();  
  55. //                  return s1.getName().compareTo(s2.getName());//也可以用compare来比较  
  56.                 }  
  57.                   
  58.             });  
  59.         }  
  60.         return list;  
  61.           
  62.     }  
  63. }  
创建子类继承基类:
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public class Child extends Parent<Anno>{  
  2.   
  3. }  

测试类:
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public class TestAnnotation {  
  2.   
  3.     @SuppressWarnings({ "unchecked""rawtypes" })  
  4.     public static void main(String[] args) {  
  5.         Parent c = new Child();  
  6.         List<SortableField> list = c.init();//获取泛型中类里面的注解  
  7.         //输出结果  
  8.         for(SortableField l : list){  
  9.             System.out.println("字段名称:"+l.getName()+"\t字段类型:"+l.getType()+  
  10.                     "\t注解名称:"+l.getMeta().name()+"\t注解描述:"+l.getMeta().description());  
  11.         }  
  12.     }  
  13. }  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值