分享知识 传递快乐
1. 基本语法
注解在Java中与类、接口、枚举类似,使用 @interface 关键字修饰类的类型。
public @interface Example {
String value() default "";
}
使用 @interface 自定义注解时,自动继承了 java.lang.annotation.Annotation 接口。注解时不能继承其他的注解或接口。@interface 用来声明的方法名称就是参数的名称,返回值类型就是参数的类型(返回值类型只能是基本类型、Class、String、enum)。可以通过 default 来声明参数的默认值。
定义注解格式:
public @interface 注解名 {定义体}
注解参数的可支持数据类型:
- 基本类型(int,float,boolean,byte,double,char,long,short)
- String类型
- Class类型
- enum类型
- Annotation类型
- 以上所有类型的数组
定义注解类型元素时需要注意如下几点:
- 访问修饰符必须为public,不写默认为public;
- 该元素的类型只能是基本数据类型、String、Class、枚举类型、注解类型(体现了注解的嵌套效果)以及上述类型的一位数组;
- 该元素的名称一般定义为名词,如果注解中只有一个元素,请把名字起为value(后面使用会带来便利操作);
- ()不是定义方法参数的地方,也不能在括号中定义任何参数,仅仅只是一个特殊的语法;
- default代表默认值,值必须和第2点定义的类型一致;
- 如果没有默认值,代表后续使用注解时必须给该类型元素赋值。
2. 元注解:
元注解的作用就是负责注解其他注解。
- @Target
- @Retention
- @Documented
- @Inherited
这些类型和它们所支持的类在 java.lang.annotation 包中可以找到。
2.1 @Target
@Target 注解是专门用来限定某个自定义注解能够被应用在哪些Java元素上面使用。
@Target 修饰范围:可被用于 packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。在Annotation类型的声明中使用了 target 可更加明晰其修饰的目标。
@Target 作用:用于描述注解的使用范围。
@Target 使用的一个枚举类型:
public enum ElementType {
/** 用于描述类,接口(包括注解类型)或枚举的声明 */
TYPE,
/** 属性的声明 */
FIELD,
/** 方法的声明 */
METHOD,
/** 方法形式参数声明 */
PARAMETER,
/** 构造方法的声明 */
CONSTRUCTOR,
/** 局部变量声明 */
LOCAL_VARIABLE,
/** 注解类型声明 */
ANNOTATION_TYPE,
/** 包的声明 */
PACKAGE
}
示例:
// 可以用于注解类、接口(包括注解类型) 或enum声明
@Target(ElementType.TYPE)
public @interface Example1 {
}
// 仅可用于注解类的成员变量
@Target(ElementType.FIELD)
public @interface Example2 {
}
// 可以用于注解参数、方法
@Target({ ElementType.PARAMETER, ElementType.METHOD })
public @interface Example3 {
}
2.2 @Retention
@Retention 定义了该 Annotation 被保留的时间长短,用来修饰自定义注解的生命力。
作用:用于描述注解的生命周期或被描述的注解在什么范围内有效
注解的生命周期有三个阶段:
- Java源文件阶段;
- 编译到class文件阶段;
- 运行期阶段。
@Retention 注解使用了 RetentionPolicy 枚举类型定义了三个阶段:
public enum RetentionPolicy {
// 在源文件中有效
SOURCE,
// 在class文件中有效
CLASS,
// 在运行时有效
RUNTIME
}
说明
- RetentionPolicy.SOURCE:这个注解它将被限定在Java源文件中,那么这个注解即不会参与编译也不会在运行期起任何作用,这个注解就和一个注释是一样的效果,只能被阅读Java文件的人看到;
- RetentionPolicy.CLASS:这个注解它将被编译到Class文件中,那么编译器可以在编译时根据注解做一些处理动作,但是运行时JVM(Java虚拟机)会忽略它,我们在运行期也不能读取到;在默认的情况下,自定义注解是使用的 RetentionPolicy.CLASS。
- RetentionPolicy.RUNTIME:这个注解可以在运行期的加载阶段被加载到Class对象中。那么在程序运行阶段,我们可以通过反射得到这个注解,并通过判断是否有这个注解或这个注解中属性的值,从而执行不同的程序代码段。我们实际开发中的自定义注解几乎都是使用的RetentionPolicy.RUNTIME;
示例:
// RetentionPolicy.RUNTIME 处理器可以通过反射获取到该注解的属性值,可以做一些运行时的逻辑处理
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Example {
public String name() default "";
public String value() default "";
}
2.3 @Documented
@Documented注解,是被用来指定自定义注解是否能随着被定义的 java 文件生成到 JavaDoc 文档当中,Documented 是一个标记注解,没有成员。
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Example {
public String name() default "";
public String value() default "";
}
2.4 @Inherited
@Inherited 注解是一个标记注解,用于指定某个自定义注解;如果写在了父类的声明部分,那么子类的声明部分也能自动拥有该注解。@Inherited 注解只对那些 @Target 被定义为 ElementType.TYPE 的自定义注解起作用。
@Inherited
public @interface Example {
public String value();
String name();
}
—————————
如有不足请留言指正
相互学习,共同进步