一、元注解
1、元注解概述
元注解:用于描述注解的注解
2、常用的元注解
(1)@Target:描述注解能够作用的位置
Target 里面是一个 ElementType[] value() 的枚举数组,这个数组里面指定了10个常量对象。
源码:
1 public enum ElementType {
2 /** Class, interface (including annotation type), or enum declaration */
3 TYPE, //表示可以作用与类、接口上
4
5 /** Field declaration (includes enum constants) */
6 FIELD, // 表示可以作用于成员变量上
7
8 /** Method declaration */
9 METHOD, // 表示可以作用与方法上
10
11 /** Formal parameter declaration */
12 PARAMETER,
13
14 /** Constructor declaration */
15 CONSTRUCTOR,
16
17 /** Local variable declaration */
18 LOCAL_VARIABLE,
19
20 /** Annotation type declaration */
21 ANNOTATION_TYPE,
22
23 /** Package declaration */
24 PACKAGE,
25
26 /**
27 * Type parameter declaration
28 *
29 * @since 1.8
30 */
31 TYPE_PARAMETER,
32
33 /**
34 * Use of a type
35 *
36 * @since 1.8
37 */
38 TYPE_USE
39 }
(2)@Retention:描述注解被保留的阶段
该注解右 RetentionPolicy 枚举类型的三个常量对象指定:
分别是:
1 public enum RetentionPolicy {
2 /**
3 * Annotations are to be discarded by the compiler.
4 */
5 SOURCE, //当前被描述的注解,不会存在 class 字节码文件中(不常用)
6
7 /**
8 * Annotations are to be recorded in the class file by the compiler
9 * but need not be retained by the VM at run time. This is the default
10 * behavior.
11 */
12 CLASS, //当前被描述的注解,会保留到class字节码文件中,但是不会被JVM读取。(不常用)
13
14 /**
15 * Annotations are to be recorded in the class file by the compiler and
16 * retained by the VM at run time, so they may be read reflectively.
17 *
18 * @see java.lang.reflect.AnnotatedElement
19 */
20 RUNTIME //当前被描述的注解,会保留到class字节码文件中,并被JVM读取到(自定义常用)
21 }
(3)@Documented:描述注解是否被抽取到 API 文档中
如果在被描述的注解A上添加了该元注解,那么当一个类B使用注解A时,注解A会被抽取到 api 文档中。
(4)@Inherited:描述注解是否被子类继承
如果在被描述的注解A上添加了该元注解,那么当一个类B使用注解A时,这个类B的子类C也会使用注解A。
二、自定义注解
1、自定义注解格式
语法格式:
元注解
【修饰符】 @interface 注解名称{
属性列表;
}
首先创建一个 MyAnno 类,然后在 cmd 窗口通过 javac 文件名.java 编译文件,接着再使用 javap 文件名.class 进行反编译。
public @interface MyAnno {}
通过反编译,我们得到一个信息:
public interface MyAnno extends java.lang.annotation.Annotation {}
总结:注解本质上就是一个接口,该接口默认继承Annotation接口
2、属性
注解既然是一个接口,那么就可以在接口中声明方法。
属性:接口中的抽象方法。
属性的返回值类型有下列取值:
① 基本数据类型
② String 类型
③ 枚举 Enum 类型
④ 注解类型
⑤ 以上类型的数组
3、属性的赋值
在注解中定义了属性,在使用时需要给属性赋值:
(1) 如果定义属性时,使用 default 关键字给属性默认初始化值,则使用注解时,可以不进行属性的赋值。
(2) 如果只有一个属性需要赋值,并且属性的名称是value,则value可以省略,直接定义值即可。
(3) 数组赋值时,值使用{}包裹。如果数组中只有一个值,则{}可以省略。
Demo:自定义一个注解
1 import java.lang.annotation.ElementType;
2 import java.lang.annotation.Retention;
3 import java.lang.annotation.RetentionPolicy;
4 import java.lang.annotation.Target;
5
6 /**
7 * 描述需要执行的类名和方法名
8 */
9 @Target({ElementType.TYPE})
10 @Retention(RetentionPolicy.RUNTIME)
11 public @interface Pro {
12
13 String className();
14 String methodName();
15 }
总结:注解是给编译器,解析程序使用的;注解不是程序的一部分。