4Java反射与泛型——2注解——2定义注解(廖雪峰)

1注解

使用@interface定义注解(Annotation):

  • 注解的参数类似无参数方法
  • 可以设定一个默认值(推荐)
  • 把最常用的参数命名为value(推荐)
public @interface Report {
    int type() default 0;
    String level() default "info";
    String value() default "";
}

2元注解(meta annotation)

一个是Target,一个是Rentention

使用@Target定义Annotation可以被应用于源码的那些位置

  • 类或接口:ElementType.TYPE
  • 字段:ElementType.FIELD
  • 方法:ElementType.METHOD
  • 构造方法:ElementType.CONSTRUCTOR
  • 方法参数:ElementType.PARAMETER
@Target({
    ElementType.METHOD,
    ElementType.FIELD
})//可以传入一个或多个,该段表示可以应用于字段和方法中
public @interface Report {
    int type() default 0;
    String level() default "info";
    String value() default "";
}

使用@Retention定义Annotation的生命周期:

  • 仅编译期:RetentionPolicy.SOURCE,编译器在编译时直接丢弃,不会保存到class文件中
  • 仅class文件:Retention.CLASS,该Annotation仅存储在class文件中,不会被读取
  • 运行期:Retention.RUNTIME,在运行期可以读取该Annotation

如果@Retention不存在,则该Annotation默认为CLASS,通常自定义的Annotation都是RUNTIME

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

使用@Repeatable定义Annotation是否可重复

  • JDK >= 1.8
@Repeatable
@Target(ElementType.TYPE)
public @interface Report {
    int type() default 0;
    String level() default "info";
    String value() default "";
}

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

}

使用@Inherited定义子类是否可继承父类定义的Annotation

  • 仅针对@Target为TYPE类型的Annotation
  • 仅针对class的继承
  • 对interface的继承无效
@Inherited
@Target(ElementType.TYPE)
public @interface Report {
    int type() default 0;
    String level() default "info";
    String value() default "";
}

@Report(type=1)
public class Person{

}
public class Student extends Person{

}

定义Annotation的步骤:

  • 用@interface定义注解
  • 用元注解(meta annotation)配置注解
    • Target:必须设置
    • Retention:一般设置为RUNTIME
    • 通常不必写@Inherited,@Repeatable等等
  • 定义注解参数和默认值
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Report {
    int type() default 0;
    String level() default "info";
    String value() default "";
}

3代码演示

//第一个注解,表示字段和参数不能为空
@Target({ElementType.FIELD,ElementType.PARAMETER})
public @interface NotNull {
    
}
//第二个注解,表示1-100的范围
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Range {
	
	int min() default 1;
	int max() default 100;
}
public class Person {
	
    @NotNull
    public String name;
	
    @Range(max = 20)//注解最大值为20
    public int age;
	
    public Person(@NotNull String name,int age) {//name不能为空
	this.name = name;
	this.age = age;
    }
		
}

4总结

  • 使用@interface定义注解
  • 可定义多个参数和默认值,核心参数使用value名称
  • 必须设置@Target来指定Annotation可以应用的范围
  • 应当设置@Retention为RUNTIME便于运行期读取该Annotation
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小夏天禧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值