java基础-Annotation

在使用spring框架的时候,会提供很多注解例如 @Autowired、@Bean等。Spring 通过扫描注解,在标注了过注解的地方会执行特定操作。如实例化Bean,注入Bean。所以注解的用法已经比较清楚,接下来开始实战:

先看看别人定义的注解:

@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
    boolean required() default true;
}
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
    @AliasFor(
        annotation = Controller.class
    )
    String value() default "";
}
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ResponseBody {
}

 

@Target:定义注解可以标注的范围,选项参考ElementType枚举类:

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
}

 

@Retention:定义注解的生命周期,选项参考RetentionPolicy

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
}

生命周期的大小 SOURCE < CLASS < RUNTIME

SOURCE:在源码中保留,编译时无效。(检测代码是否正确可用)

CLASS:编译有效,JVM加载时无效。(编译时做预处理可用)

RUNTIME:JVM加载运行时仍然有效。(运行时可用)

 

@Documented:生成文档是如果使用该注解修饰的,被标注的元素的API文档中将会包含该注解说明。

 

@Inherited:在标注的注解会被继承获取。如果A是B的父类,A使用了@Inherited注解。Class<B>调用getAnnotations()的时候,会获取Class<A>标记的注解,如果未使用@Inherited注解不获取。

 

有了基本的理论知识开始测试:

1、定义一个annotation

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface FirstAnnotation {

    /**
     * 定义一个枚举类型
     */
    ModelEnum type() default ModelEnum.B;

    /**
     * 定义一个枚举数组类型
     */
    ModelEnum[] types() default {};

    /*
     * 定义一个数字类型
     */
    int id() default 99;

    /**
     * 定义一个数字数组类型
     */
    int[] ids() default {};

    /*
     * 定义一个字符类型
     */
    String name() default "";

    /*
     * 定义一个字符数组类型
     */
    String[] names() default {};

}
public enum ModelEnum {
    A,
    B,
    C
}
public class Model {

    @FirstAnnotation(ids = {1, 2, 3, 4, 5}, types = {ModelEnum.A, ModelEnum.B})
    public String field1;

}

编写测试类

public class Test {
    public static void main(String[] args) throws Exception {
        Class<Model> modelClass = Model.class;

        // 获取字段1
        Field field1 = modelClass.getField("field1");
        FirstAnnotation firstAnnotation = field1.getAnnotation(FirstAnnotation.class);
        System.out.println(firstAnnotation.id());
        for (int id : firstAnnotation.ids()) {
            System.out.print(id + "\t");
        }
        System.out.println(firstAnnotation.name());
        for (String name : firstAnnotation.names()) {
            System.out.print(name + "\t");
        }
        System.out.println(firstAnnotation.type());
        for (ModelEnum modelEnum : firstAnnotation.types()) {
            System.out.print(modelEnum.name() + "\t");
        }
    }

}
打印结果:
99
1	2	3	4	5	
B
A	B	

经过测试已经完成了自定义注解。

 

接下来测试@Inherited

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface InheritableAnnotation {

}
@InheritableAnnotation
public class ModelParent {
    private String f1;
}
// 继承ModelParent
public class Model extends ModelParent {
    ...
}
public class Test {
    public static void main(String[] args) throws Exception {
        Class<Model> modelClass = Model.class;

        // 获取class注解
        Annotation[] annotations = modelClass.getAnnotations();
        for (Annotation annotation : annotations) {
            String name = annotation.annotationType().getName();
            System.out.println(name);
        }
    }
}
打印结果:
com.pss.annotation.InheritableAnnotation

再删除@Inherited 测试

打印结果:

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值