深入理解Java的Annotation系列-第二部分 自定义注解

来源:互联网 发布:上瘾网络剧类似的 编辑:程序博客网 时间:2024/06/08 14:16

七、元注解

   J2SE5.0版本在 java.lang.annotation提供了四种元注解,专门注解其他的注解:

@Documented:注解是否将包含在JavaDoc
@Retention
:什么时候使用该注解
@Target
:注解用于什么地方
@Inherited
是否允许子类继承该注解

    7.1 @Documented:一个简单的Annotations标记注解,表示是否将注解信息添加到Java文档中。

   7.2 @Retention:定义该注解的生命周期,其中Retention保持、保留的意思,RetentionPolicy:保持、保留政策、方针、策略。

    Java编译器编译时,它会识别在源代码里添加的注解是否还会保留,这就是RetentionPolicy。下面是Java定义的RetentionPolicy枚举:

    编译器的处理有三种策略:

    将注解保留在编译后的类文件中,并在第一次加载类时读取它;RUNTIME

    将注解保留在编译后的类文件中,但是在运行时忽略它;CLASS

    按照规定使用注解,但是并不将它保留到编译后的类文件中;SOURCE

    Java源码:

    public enum RetentionPolicy {

    SOURCE,// 此类型会被编译器丢弃

     CLASS,// 此类型注解会保留在class文件中,但JVM会忽略它

     RUNTIME// 此类型注解会保留在class文件中,JVM会读取它

   }

   1RetentionPolicy.SOURCE :保留注解到java源文件阶段,即在编译阶段丢弃,这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码,@Override, @SuppressWarnings都属于这类注解。

   2RetentionPolicy.CLASS:在类加载的时候丢弃,在字节码文件的处理中有用,这是注解默认的方式。

   3RetentionPolicy.RUNTIME:始终不会丢弃,运行期也保留该注解,保留注解到运行时阶段即内存中的字节码,因此可以使用反射机制读取该注解的信息。我们自定义的注解通常使用这种方式。

  7.3  @Target:表示该注解用于什么地方,如果不明确指出,该注解可以放在任何地方。  Java源码:

public enum ElementType {

     TYPE,// 用于类,接口,枚举但不能是注解

       FIELD,//字段上,包括枚举值

     METHOD,//方法,不包括构造方法

       PARAMETER,// 方法的参数

     CONSTRUCTOR,// 构造方法

     LOCAL_VARIABLE,// 本地变量或catch语句

     ANNOTATION_TYPE,//注解类型(无数据)

      PACKAGE//Java

}

    7.4 @Inherited 定义该注释和子类的关系

  @Inherited元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。

八、自定义注解

   使用@interface自定义注解,语法格式如下:public @interface注解名 {定义体},它自动继承了java.lang.annotation.Annotation接口,由编译程序自动完成其他细节。在定义注解时,不能继承其他的注解或接口,

    @interface用来声明一个注解,其中的每一个方法实际上是声明了一个配置参数。方法的名称就是参数的名称,返回值类型就是参数的类型,这种类型包括:

        1、所有基本数据类型(int,float,boolean,byte,double,char,long,short)
2String类型
3Class类型
4enum类型
5Annotation类型
6、以上所有类型的数组

    可以通过default来声明参数的默认值。

Annotation类型里面的参数怎么设定?常遵循如下规范:
  第一:只能用public或默认(default)这两个访问权修饰。

      例如,String value();这里把方法设为defaul默认类型; 
  第二:参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和 String,Enum,Class,annotations等数据类型,以及这一些类型的数组.例如,String value();这里的参数成员就为String;
  第三:如果只有一个参数成员,最好把参数名称设为"value",后加小括号。

 自定义注解的简单例子:

  第一步:定义注解

package annotation.self;

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

/**

 * 宠物名称注解

 * @authorchenzhengfeng

 */

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

public @interface PetName {

   String value() default"";

}

package annotation.self;

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

/**

 * 宠物类型注解

 * @authorchenzhengfeng

 *

 */

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

public @interface PetType {

    /**

     * 类型枚举

     */

    public enum Type{CAT,DOG,PIG,SNAKE};

    /**

     * 类型属性

     */

    Type pet_type() default Type.DOG;

}

 

第二步:应用注解:

   定义了注解,并在需要的时候给相关类,类属性加上注解信息即可,如下例。

    packagepet;

importjava.lang.annotation.Annotation;

importannotation.self.PetName;

importannotation.self.PetType;

importannotation.self.PetType.Type;

@PetName("mimi")

@PetType(pet_type =Type.PIG)

public class Pet {

    private String petName;

    private String petType;

    public String showAll() {

       return this.petName + " " + this.petType;

    }

    public String getPetName() {

       return petName;

    }

    public void setPetName(String petName) {

       this.petName = petName;

    }

    public String getPetType() {

       return petType;

    }

    public void setPetType(String petType) {

       this.petType = petType;

    }

    public static void main(String[] args) {

       Pet pet1 = new Pet();

       System.out.println(pet1.showAll());

      

    }

}

   通过以上例子,可以看出如果没有响应的注解信息处理流程,注解可以说是没有实用价值。

如何让注解真真的发挥作用,主要就在于注解处理方法,下一步我们将学习注解信息的获取和处理。

阅读全文
0 0