Java自定义注解和运行时靠反射获取注解

原文地址:http://blog.csdn.net/bao19901210/article/details/17201173


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

1、元注解

元注解是指注解的注解。包括  @Retention @Target @Document @Inherited四种。


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

@Retention(RetentionPolicy.SOURCE)   //注解仅存在于源码中,在class字节码文件中不包含

@Retention(RetentionPolicy.CLASS)     // 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得,

@Retention(RetentionPolicy.RUNTIME)  // 注解会在class字节码文件中存在,在运行时可以通过反射获取到

注解类:

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

实体类:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public  class  Anno {
 
     @FieldMeta (id= true ,name= "序列号" ,order= 1 )
     private  int  id;
     @FieldMeta (name= "姓名" ,order= 3 )
     private  String name;
     @FieldMeta (name= "年龄" ,order= 2 )
     private  int  age;
     
     @FieldMeta (description= "描述" ,order= 4 )
     public  String desc(){
         return  "java反射获取annotation的测试" ;
     }
     
     public  int  getId() {
         return  id;
     }
     public  void  setId( int  id) {
         this .id = id;
     }
     public  String getName() {
         return  name;
     }
     public  void  setName(String name) {
         this .name = name;
     }
     public  int  getAge() {
         return  age;
     }
     public  void  setAge( int  age) {
         this .age = age;
     }
     
}

获取到注解的帮助类

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
public  class  SortableField {
 
     public  SortableField(){}
     
     public  SortableField(FieldMeta meta, Field field) {
         super ();
         this .meta = meta;
         this .field = field;
         this .name=field.getName();
         this .type=field.getType();
     }
     
     
     public  SortableField(FieldMeta meta, String name, Class<?> type) {
         super ();
         this .meta = meta;
         this .name = name;
         this .type = type;
     }
 
 
     private  FieldMeta meta;
     private  Field field;
     private  String name;
     private  Class<?> type;
     
     public  FieldMeta getMeta() {
         return  meta;
     }
     public  void  setMeta(FieldMeta meta) {
         this .meta = meta;
     }
     public  Field getField() {
         return  field;
     }
     public  void  setField(Field field) {
         this .field = field;
     }
     public  String getName() {
         return  name;
     }
     public  void  setName(String name) {
         this .name = name;
     }
 
     public  Class<?> getType() {
         return  type;
     }
 
     public  void  setType(Class<?> type) {
         this .type = type;
     }
     
     
}

运行时获取注解,首先创建一个基类:

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

创建子类继承基类:

?
1
2
3
public  class  Child  extends  Parent<Anno>{
 
}

测试类:

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值