分享

注解的定义与反射调用

 I_T_馆 2014-07-21
首先我们来看如何定义注解:看下面这个图。

 
 
这里有三个类:
第一个类:定义注解类。
第二个类:定义基本类,在类上使用了注解
第三个类:调用第二个类。判断第二个类上是否使用了注解。

 ItcastAnnotation.java定义了一个注解类,就是在interface前加了一个@符号
 
我们定义了一个AnnotationTest类,在这个类上使用了注解@ItcastAnnotation.
然后我们在独立于任何一个类的main方法里测试,看看AnnotationTest上是否加了@ItcastAnnotation注解.

 
我们会发现,如果在ItcastAnnotation.java类上没有@Retention(RetentionPolicy.RUNTIME).那么在main方法中运行时什么都没有,也就是if语句中的内容为false.那为什么呢?这就涉及了@Retention的作用。

下面说说@Retention注解的作用:

@Retention(RetentionPolicy.RUNTIME)这个注解是定义在注解上的注解,叫元注解.

每一个注解的生命周期有三个阶段:源文件   -->  class 文件  --> 内存中的字节码文件

 加@Retention这个注解,就是为了注明,我的Annotation生命周期在哪个阶段.是在源文件阶段呢?还是在class

 文件阶段呢?还是在内存中字节码文件的阶段呢?


这里有一个问题,什么字节码?class文件时字节码文件么?不是。

这里引出一个概念:字节码。:class文件不是字节码,class文件再被用到的时候,由类加载器把文件加载进来以后,类加载器会对加载的文件进行处理。处理完以后在内存中的东西才是字节码。


Retention可以在您定义Annotation型态时,指示编译器如何对待您的自定义 Annotation,默认编译器会将Annotation资讯留在class档中,但不能被虚拟机器读取,而仅用于编译器或工具运行时提供资讯。

 在使用Retention型态时,需要提供java.lang.annotation.RetentionPolicy的列举型态:

                  public enum RetentionPolicy {

                          SOURCE, //第一阶段  源文件   编译器处理完Annotation资讯后就没事了

                          CLASS, //第二阶段  class文件   编译器将Annotation储存于class档中,预设

                          RUNTIME //第三阶段  内存中的字节码文件    编译器将Annotation储存于内存中,可由VM读入

                  } 


具体可以查看JDK API @Retention

接下来我们来看另一个注解@Target(ElementType.METHOD)。

目标,顾名思义,也就是这个注解应用在哪里。ElementType.METHOD:意思是应用在方法上。也即是说我定义的这个ItcastAnnotation注解应用在方法上。
 
 
所以,下面这个方法报错了。

 
那如果我们想让这个注解在类和方法上都有效,应该怎么写呢?
 
 
大家一定感到很奇怪,允许在类上面加注解,为什么是ElementType.TYPE呢?下面我们来看看API文档
 
 
 我们发现,原来Type是Class的父类,那么我都允许这个注解在父类上使用了,那自然也可以在子类中使用了。我们知道除了Class:类,还有interface:接口等。而Type是class和interface,enum这一系列类型的父类。也就是说,加上ElementType.TYPE以后,不紧可以再Class上使用这个注解,在接口上也可以使用这个注解了,还可以放在枚举上。

 小技巧:如果你记不住这两个元注解。那么你记住了@override就可以了,查看api,就知道这两个元注解了。如下:
 
 


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多