注解,其实就是这么简单( 二 )


3.1@Target@Target用于描述注解的使用范围 , 即被描述的注解可以用到什么地方 , @Target注解内定义了ElemenType[]数组 , 数组以枚举类的形式定义了注解的修饰范围 。 通过下面的源代码我们可以看出 , 该注解能够用于类、接口、构造器、属性和方法、参数声明、注解声明等
源代码如下
@Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.ANNOTATION_TYPE)public @interface Target {ElementType[] value();}复制代码public enum ElementType {/** Class, interface (including annotation type), or enum declaration */TYPE,/** Field declaration (includes enum constants) */FIELD,/** Method declaration */METHOD,/** Formal parameter declaration */PARAMETER,/** Constructor declaration */CONSTRUCTOR,/** Local variable declaration */LOCAL_VARIABLE,/** Annotation type declaration */ANNOTATION_TYPE,/** Package declaration */PACKAGE,/*** Type parameter declaration** @since 1.8*/TYPE_PARAMETER,/*** Use of a type** @since 1.8*/TYPE_USE}复制代码3.2@Rentention@Rentention表示需要在什么级别保存该注释信息 , 用于描述注解的生命周期 , 通过源代码 , 我们可以看出 , 注解内有个RetentionPolicy的值 , 我们继续深入往下看 , RetentionPolicy是个枚举类型的值 , 它有三个值可供选择 , SOURCE是在源代码层面 , 在编译是将会失效;CLASS作用在class文件中 , 但是在运行时失效;RUNTIME在运行时依旧保留该注解 , 因此可以通过反射机制来读取注解内的信息 。 因此 , 这三个值对应的生命周期大小为:SOURCE 源代码如下:
@Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.ANNOTATION_TYPE)public @interface Retention {/*** Returns the retention policy.* @return the retention policy*/RetentionPolicy value();}复制代码public enum RetentionPolicy {/*** Annotations are to be discarded by the compiler.*/SOURCE,/*** Annotations are to be recorded in the class file by the compiler* but need not be retained by the VM at run time.This is the default* behavior.*/CLASS,/*** Annotations are to be recorded in the class file by the compiler and* retained by the VM at run time, so they may be read reflectively.** @see java.lang.reflect.AnnotatedElement*/RUNTIME}复制代码3.3@Documented@Documented表明该注解将被包含在javadoc中 。 该注解用的相对较少 。
源代码如下:
@Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.ANNOTATION_TYPE)public @interface Documented {}复制代码3.4@Inherited@Inherited说明子类可以继承父类中的该注解
@Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.ANNOTATION_TYPE)public @interface Inherited {}复制代码4、自定义注解通过使用元注解的组合 , 我们可以按照自己的需求来自定义注解 , 我们通常使用@interface来自定义注解 , 它自动继承了java.lang.annotation.Annotation接口 。 接下 , 我们来以一段代码仔细分析下如何自定义注解:

  • 注解一
public @interface MyAnnotation{}复制代码注解一是一个最简单的自定义注解 , 我们可以看到 , 它以public修饰 , 以@interface用来声明一个注解 , 具体的格式为:public @interface 注解名{定义内容} , 如果要在注解内添加一个参数 , 该怎样定义呢?
  • 注解二
@Retention(value = http://kandian.youth.cn/index/RetentionPolicy.RUNTIME)@interface myAnnotantion3{//参数名为vale , 当注解内只有一个参数 , 使用注解时 , 参数名可省略String value();}复制代码特别需要注意的是 , 注解内的方法名称就是参数的名称 , 而返回值类型就是参数类型 , 我们可以这样使用
@Retention(value = http://kandian.youth.cn/index/RetentionPolicy.RUNTIME)@myAnnotantion3("snow")public void test2(){}复制代码因为注解内只有一个参数 , 所以在使用注解时 , 参数名称是可以省略的 。
如果 , 我们我们想添加多个的参数值 , 该怎么自定义注解呢
  • 注解三
Target(value = http://kandian.youth.cn/index/{ElementType.METHOD,ElementType.TYPE})@Retention(value = RetentionPolicy.RUNTIME)@interface myAnnotaion2{/***表示注解的参数 , name参数名 , String 表示参数的类型* 参数加default , 在注解内可写可不写*/String name();int age();int id();}复制代码同理 , 我们只需要在相应的位置引用该注解即可
@myAnnotaion2(name = "Simon",age=25 , id=23)public void test1(){}复制代码如果我们向给注解内的参数设定默认值 , 我们可以这样做
  • 注解四
@Target(value = http://kandian.youth.cn/index/{ElementType.METHOD,ElementType.TYPE})@Retention(value = RetentionPolicy.RUNTIME)@interface myAnnotaion2{/***表示注解的参数 , name参数名 , String 表示参数的类型* 参数加default , 在注解内可写可不写*/String name() default"";int age() default 0;int id() default -1;}复制代码