java 注解的基本原理和编程实现

  java 1.5开始引入了注解和反射,正确的来说注解是反射的一部分,没有反射,注解无法正常使用,但离开注解,反射依旧可以使用,因此来说,反射的定义应该包含注解才合理一些。
当然,这只是个人想法,至于java官方为什么这么泾渭分明不得而知,最重要的是如何使用注解。

注解的功能分为2部分:

  1. 作为特定的标记

  2. 额外信息的载体


>>>>定义一个UserAnnotation注解类

?
1
2
3
4
5
6
7
8
@Target(value = { ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public  @ interface  UserAnnotation {
     public  int id()  default  0;
     public  String name()  default  "" ;
     public  int age()  default  18;
     public  String gender()  default  "M" ;
}

其中@target个@Retention本身就是注解

【@target】这个注解来指定给哪一类java成员注解,指定注解目标该是什么样的东西

注解@Target的源码

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)  //这不是在作弊,这确实是自己注解自己,所以说注解也可以被字节给注解
public  @ interface  Target {
     ElementType[] value();  //值可以使数组 value={...}
}
 
public  enum ElementType {
     TYPE,   //给类(型)注解
     FIELD,  //给字段注解,不要忘了,字段可以是对象
     METHOD,  //给方法注解
     PARAMETER,  //给参数注解
     CONSTRUCTOR,  //给构造方法注解
     LOCAL_VARIABLE,  //给局部变量注解
     ANNOTATION_TYPE, //给注解注解(这貌似把自己不当类来看)
     PACKAGE,  //给包注解
     TYPE_PARAMETER,  //不知道,等知道了我再写在这里
     TYPE_USE  //这个也不知道
}

【@Retention】表示注解运行的状态,换句话说,注解改在什么样的状态下才能运行

注解@Retention的源码

?
1
2
3
4
5
6
7
8
9
10
11
12
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public  @ interface  Retention {
     RetentionPolicy value();
}
 
public  enum RetentionPolicy {
     SOURCE,  //源码状态运行,
     CLASS,  //编译类文件时运行
     RUNTIME  //运行时运行
}

一般来说,源码状态运行和编译状态运行的注解往往和编译器相关,比如报错,警告,类编译参数等,这2类状态一般和编辑器插件关系密切,这里不再讨论

在日常开发中RUNTIME用的最多,这是开发人员可以控制的一个状态。


【@Documented】额,不多解释,具体来说是生成说明文档时把类的解释添加进去


关于注解的方法说明,注解只有方法,没有字段,因为注解也是一个interface,只不过前面加了一个@符号,还有一点是这些方法无法实现,写法和C++的纯虚函数相似

请看id()方法的解释

?
1
2
3
4
5
6
  public  int id()  default  0; 
/*首先,方法必须是public的,去掉public,默认也是public,接口interface不也是这样么
  *
  *其次,default默认值不是必须的,方法必须有返回值,返回值可以是java中复杂对象,也可以是基本类型,枚举都行
  *如 ElementType[] value();
  */


注解定义好了,怎么使用呢,如下

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public  class  TestMain
{
   @UserAnnotation(age=20,gender= "F" ,id=2014,name= "zhangsan" ) //注解的使用
   private  Object obj;
   
   public  static  void main(String[] args) throws Exception
   {
      Filed objField = TestMain. class .getField( "obj" );
      UserAnnotation ua = objField.getAnnotation(UserAnnotation. class ); //得到注解,起到了标记的作用
      
     System.out.println(ua.age()+ "," +ua.gender()+ "," +ua.id()+ "," +ua.name());
     //***进一步操作的话,假设Object要指向一个User类,那么可以讲注解的值给他
     TestMain tm =  new  TestMain();
     objFiled.set(tm, new  User(ua.age(),ua.gender(),ua.id(),ua.name()));  //不错吧,将自己的信息送给obj,起到了附加信息的作用
     
     //-----------请自由遐想吧~~,下面来说说注解怎么能获得注解自己的注解-------------
    Target t = ua.annotationType().getAnnotation(Target. class )
    ElementType[] values = t.value();
    //~~~~~~~~~~~~~~完了,再一次自由遐想吧~~~~~~~~~~~~~~
    
    Sysout.out.println( "注意:是遐想,不是瞎想!!" );
   }
}


try doing it.

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值