阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

定义注解

33次阅读
没有评论

共计 2597 个字符,预计需要花费 7 分钟才能阅读完成。

Java 语言使用 @interface 语法来定义注解(Annotation),它的格式如下:

public @interface Report {int type() default 0;
    String level() default "info";
    String value() default "";
}

注解的参数类似无参数方法,可以用 default 设定一个默认值(强烈推荐)。最常用的参数应当命名为value

元注解

有一些注解可以修饰其他注解,这些注解就称为元注解(meta annotation)。Java 标准库已经定义了一些元注解,我们只需要使用元注解,通常不需要自己去编写元注解。

@Target

最常用的元注解是 @Target。使用@Target 可以定义 Annotation 能够被应用于源码的哪些位置:

  • 类或接口:ElementType.TYPE
  • 字段:ElementType.FIELD
  • 方法:ElementType.METHOD
  • 构造方法:ElementType.CONSTRUCTOR
  • 方法参数:ElementType.PARAMETER

例如,定义注解 @Report 可用在方法上,我们必须添加一个@Target(ElementType.METHOD)

@Target(ElementType.METHOD)
public @interface Report {int type() default 0;
    String level() default "info";
    String value() default "";
}

定义注解 @Report 可用在方法或字段上,可以把 @Target 注解参数变为数组{ElementType.METHOD, ElementType.FIELD}

@Target({
    ElementType.METHOD,
    ElementType.FIELD
})
public @interface Report {...}

实际上 @Target 定义的 valueElementType[]数组,只有一个元素时,可以省略数组的写法。

@Retention

另一个重要的元注解 @Retention 定义了 Annotation 的生命周期:

  • 仅编译期:RetentionPolicy.SOURCE
  • 仅 class 文件:RetentionPolicy.CLASS
  • 运行期:RetentionPolicy.RUNTIME

如果 @Retention 不存在,则该 Annotation 默认为 CLASS。因为通常我们自定义的Annotation 都是 RUNTIME,所以,务必要加上@Retention(RetentionPolicy.RUNTIME) 这个元注解:

@Retention(RetentionPolicy.RUNTIME)
public @interface Report {int type() default 0;
    String level() default "info";
    String value() default "";
}

@Repeatable

使用 @Repeatable 这个元注解可以定义 Annotation 是否可重复。这个注解应用不是特别广泛。

@Repeatable(Reports.class)
@Target(ElementType.TYPE)
public @interface Report {int type() default 0;
    String level() default "info";
    String value() default "";
}

@Target(ElementType.TYPE)
public @interface Reports {Report[] value();}

经过 @Repeatable 修饰后,在某个类型声明处,就可以添加多个 @Report 注解:

@Report(type=1, level="debug")
@Report(type=2, level="warning")
public class Hello {
}

@Inherited

使用 @Inherited 定义子类是否可继承父类定义的 Annotation@Inherited 仅针对 @Target(ElementType.TYPE) 类型的 annotation 有效,并且仅针对 class 的继承,对 interface 的继承无效:

@Inherited
@Target(ElementType.TYPE)
public @interface Report {int type() default 0;
    String level() default "info";
    String value() default "";
}

在使用的时候,如果一个类用到了@Report

@Report(type=1)
public class Person {
}

则它的子类默认也定义了该注解:

public class Student extends Person {
}

如何定义 Annotation

我们总结一下定义 Annotation 的步骤:

第一步,用 @interface 定义注解:

public @interface Report {
}

第二步,添加参数、默认值:

public @interface Report {int type() default 0;
    String level() default "info";
    String value() default "";
}

把最常用的参数定义为value(),推荐所有参数都尽量设置默认值。

第三步,用元注解配置注解:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Report {int type() default 0;
    String level() default "info";
    String value() default "";
}

其中,必须设置 @Target@Retention@Retention一般设置为 RUNTIME,因为我们自定义的注解通常要求在运行期读取。一般情况下,不必写@Inherited@Repeatable

小结

Java 使用 @interface 定义注解;

可定义多个参数和默认值,核心参数使用 value 名称;

必须设置 @Target 来指定 Annotation 可以应用的范围;

应当设置 @Retention(RetentionPolicy.RUNTIME) 便于运行期读取该Annotation

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2024-08-05发表,共计2597字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中