Java注解:@Retention和@Target注解的说明以及使用方法

本文目录

一、注解说明

二、@Target注解

三、@Retention注解

四、自定义注解


一、注解说明

注解(也被称为元数据)为我们在代码中添加信息提供了一种形式化的方法,使我们可以在稍后某个时刻非常方便地使用这些数据。

定义注解时,会需要一些元注解(meta--annotation),如@Target@ Retention,这两个特性是我们必须要定义清楚的,一个是Target(注解目标),另一个就是Retention(注解生命周期,也叫声明周期)。

@Target用来定义你的注解将应用于什么地方(例如是一个方法或者一个域)。

@ Retention用来定义该注解在哪一个级别可用,在源代码中(SOURCE)类文件中(CLASS)或者运行时(RUNTIME)

在注解中,一般都会包含一些元素以表示某些值。当分析处理注解时,程序或工具可以利用这些值。注解的元素看起来就像接口的方法,唯一的区别是你可以为其指定默认值。

没有元素的注解称为标记注解(marker annotation),例如我在文章尾部自定义的注解。

Java目前只内置了三种标准注解(下一篇文章介绍),以及四种元注解。元注解专职负责注解其他的注解。

二、@Target注解

下面是注解@Target的源码,这里要一个ElementType[]数组。

 /**
  * @since 1.5
  * @jls 9.6.4.1 @Target
  * @jls 9.7.4 Where Annotations May Appear
  */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
    /**
     * Returns an array of the kinds of elements an annotation type
     * can be applied to.
     * @return an array of the kinds of elements an annotation type
     * can be applied to
     */
    ElementType[] value();
}

而ElementType是枚举类型的,一共有10种取值类型,分别是(TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, ANNOTATION_TYPE, PACKAGE, TYPE_PARAMETER, TYPE_USE)以下是ElementType的源码:

 /**
  * @author  Joshua Bloch
  * @since 1.5
  * @jls 9.6.4.1 @Target
  * @jls 4.1 The Kinds of Types and Values
  */
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注解

如下是@Retention注解的源码信息,它要求一个RetentionPolicy类型的取值。我们再看看RetentionPolicy是个什么类型对象。

/** 
 * @author  Joshua Bloch
 * @since 1.5
 * @jls 9.6.3.2 @Retention
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    /**
     * Returns the retention policy.
     * @return the retention policy
     */
    RetentionPolicy value();
}

点击进入RetentionPolicy对象之后,发现它是一个枚举类型的,有三种取值(SOURCE, CLASS, RUNTIME),以下是RetentionPolicy枚举源码:

/**
 * @author  Joshua Bloch
 * @since 1.5
 */
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
}

四、自定义注解

看完源码之后,发现自定义注解其实也不难,比葫芦画瓢,我们也自定义注解试一下。

@Target({ElementType.METHOD, ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.CLASS)
public @interface TestAnnotation {

}

定义完之后,就可以使用自己定义的注解了,例如:

@TestAnnotation
public class Sort {

    public static void main(String[] args) {
        System.out.println("自定义注解使用中.....");
    }

}

 

【参考资料】

Thinking in Java(Fouth Edition) ---- Java编程思想(第四版):第20章 注解

Java注解:三种标准注解和四种元注解以及注解的元素:https://blog.csdn.net/weixin_44299027/article/details/105920418

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章