本文目录
一、注解说明
注解(也被称为元数据)为我们在代码中添加信息提供了一种形式化的方法,使我们可以在稍后某个时刻非常方便地使用这些数据。
定义注解时,会需要一些元注解(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