Java 自定义注解
1. 注解定义
- 注解是一种能被添加到java代码中的元数据,类、方法、变量、参数和包都可以用注解来修饰。注解对于它所修饰的代码并没有直接的影响。
2. 使用范围
- 注解有许多用法
- 为编译器提供信息
- 注解能被编译器检测到错误或抑制警告
- 编译时和部署时的处理
- 软件工具能处理注解信息从而生成代码,XML文件等等
- 运行时的处理
- 有些注解在运行时能被检测到
3. 自定义注解
3.1 基本语法
-
public @interface MyAnnotation { /** * @Author: Hjx * @Date: 2021/8/16 16:57 */ public @interface MyAnnotation { /** * 在类中会定义构造、属性、方法等,但在自定义注解中只能定义注解类型元素 */ /** * 访问修饰符只能定义为 public 和 default,不写默认public */ public String name(); /** * default 设置默认值,没设置默认值的在使用时需要手动添加 */ int num() default 1; }
3.2 注意事项
- 在类中会定义构造、属性、方法等,但在自定义注解中只能定义注解类型元素
- 访问修饰符只能定义为 public 和 default,不写默认public
- default 设置默认值,没设置默认值的在使用时需要手动添加
- 成员参数只能使用八种基本类型(byte、short、char、int、long、float、double、boolean)和String、Enum、Class、annotations等数据类型,及其数组。
- 注解的定义通过@interface表示,所有的注解会自动继承
java.lang.Annotation
接口,且不能再继承别的类或是接口。 - 获取类方法和字段的注解信息,只能通过Java的反射技术来获取 Annotation 对象。
- 注解可以没有定义成员,只做标识。
- ()不是定义方法参数的地方,也不能在括号中定义任何参数,仅仅只是一个特殊的语法;
3.3 常用元注解
- 元注解是专门用来注解其他注解的注解。
@Target
-
用来限制注解用于什么地方,如只能注解在类、方法、属性还是构造方法等
-
@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
类型的枚举数组 -
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
-
用来修饰自定义注解的生命周期
-
注解生命周期有三个阶段:java源文件、编译class文件、运行期
-
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Retention { /** * Returns the retention policy. * @return the retention policy */ RetentionPolicy value(); }
-
属性是一个
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文件中,在运行时不会被虚拟机保留, */ 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 */ /** 会被编译期编译到class文件中,在运行时会被虚拟机保留,可通过反射获取 */ RUNTIME }
@Documented
- 表示是否将此注解的相关信息添加到javadoc文档中
@Inherited
- 定义该注解如果在父类上定义,其子类可以自动继承,注意只有注解在类上才可以生效,对方法、属性等无效。
3.4 特殊语法
- 如果注解没有注解类型元素,在使用时可以直接写为
@注解名
,()可以省略 - 如果注解类型元素只有一个,可以命名为 value,使用时可以直接
@注解名(注解值)
- 如果注解类型元素是数组,使用时只添加一个的话,可以省略{},写为
@注解名(类型名 = 类型值)