Java自定义注解

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

一、元注解

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

1.1 @Retention

定义了该Annotation被保留的时间长短

Retention允许的值

public enum RetentionPolicy {
    /**
     * 注解仅存在于源码中,在class字节码文件中不包含
     */
    SOURCE,

    /**
     * 默认的保留策略,在class文件有效,可能会被虚拟机忽略
     */
    CLASS,

    /**
     * 注解会在class字节码文件中存在,在运行时有效
     */
    RUNTIME
}

作用:表示需要在什么级别保存该注释信息,用于描述注解的生命周期(即:被描述的注解在什么范围内有效)

@Retention(RetentionPolicy.RUNTIME)
public @interface Log {

}
1.2 @Target

说明了Annotation所修饰的对象范围:Annotation可被用于 packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。在Annotation类型的声明中使用了target可更加明晰其修饰的目标。

Target允许的值

public enum ElementType {
    /** 用于描述类、接口(包括注解类型) 或enum声明 */
    TYPE,

    /** 用于描述域(包含枚举常量) */
    FIELD,

    /** 用于描述方法 */
    METHOD,

    /** 用于描述参数 */
    PARAMETER,

    /** 用于描述构造器 */
    CONSTRUCTOR,

    /** 用于描述局部变量 */
    LOCAL_VARIABLE,

    /** 用于描述注解类型 */
    ANNOTATION_TYPE,

    /** 用于描述包 */
    PACKAGE,

    /**
     * 用于描述注解的使用场景
     *
     * @since 1.8
     */
    TYPE_PARAMETER,

    /**
     * 用于描述注解的使用场景
     *
     * @since 1.8
     */
    TYPE_USE
}

作用:用于描述注解的使用范围(即:被描述的注解可以用在什么地方)

@Target(ElementType.METHOD)
public @interface Log {

}
1.3 @Documented

@Documented 将此注解包含在 javadoc 中 ,它代表着此注解会被javadoc工具提取成文档。在doc文档中的内容会因为此注解的信息内容不同而不同。

Documented是一个标记注解,没有成员。

@Documented
public @interface Log {

}
1.4 @Inherited

@Inherited 说明子类可以继承父类中的该注解,声明的此注解使用了Inherited元注解,表示此注解用在类上时,会被子类所继承

Inherited是一个标记注解,没有成员。

@Inherited 
public @interface Log {

}

二、自定义注解

使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口,由编译程序自动完成其他细节。

在定义注解时,不能继承其他的注解或接口。

@interface用来声明一个注解,其中的每一个方法实际上是声明了一个配置参数。方法的名称就是参数的名称,返回值类型就是参数的类型(返回值类型只能是基本类型、Class、String、enum)。可以通过default来声明参数的默认值。

定义注解格式:public @interface 注解名 { 定义体 }

注解参数的可支持数据类型

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

Annotation类型里面的参数设定:
1. 只能用public或默认(default)这两个访问权修饰.例如,String value();这里把方法设为defaul默认类型;   
1. 参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和 String,Enum,Class,annotations等数据类型,以及这一些类型的数组.例如,String value();这里的参数成员就为String;  
1. 如果只有一个参数成员,最好把参数名称设为”value”,后加小括号.例:下面的例子FruitName注解就只有一个参数成员。

/**
 * 自定义宠物注解
 *
 * @author Peng
 */
@Documented
@Inherited
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface PetAnnotation {
    String value() default "Cat";
}

/**
 * 自定义颜色注解
 *
 * @author Peng
 */
@Documented
@Inherited
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ColorAnnotation {
    enum Color {WHITE, BLACK, GRAY}

    Color petColor() default Color.WHITE;
}

自定义注解

/**
 * 自定义注解测试
 *
 * @author Peng
 */
public class Pet {
    @PetAnnotation
    private String petName;
    @ColorAnnotation(petColor = ColorAnnotation.Color.BLACK)
    private String color;

    public String getPetName() {
        return petName;
    }

    public void setPetName(String petName) {
        this.petName = petName;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }
}

测试类

Field[] fields = Pet.class.getDeclaredFields();
for (Field field : fields) {
    if (field.isAnnotationPresent(PetAnnotation.class)) {
        PetAnnotation pet = field.getAnnotation(PetAnnotation.class);
        System.out.println("Pet Name : " + pet.value());
    }
    if(field.isAnnotationPresent(ColorAnnotation.class)){
        ColorAnnotation color = field.getAnnotation(ColorAnnotation.class);
        System.out.println("Pet Color : " + color.petColor());
    }
}

输出:
Pet Name : Cat
Pet Color : BLACK
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值