注解的作用
注解本身没有任何意义,单独的注解就是一种注释,他需要结合反射、插桩等技术才有意义。
定义注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface Test {
String value() default "";
}
//不设置任何数值
@Test()
public class Sample {
}
//设置其他数值,但是可以省略 value
@Test("lee")
public class Sample {
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface Test {
String name() default "";
}
//不能省略 name
@Test(name = "lee")
public class Sample {
}
//多个元素
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface Test {
String value();
String name() default "";
}
@Test(value = "",name = "lee")
public class Sample {
}
不指定 Target 可以作用在任何地方
value 指定默认值,使用注解时可以不设置数值。
如果未指定默认值,必须设置数值。
value 是特殊的元素名字,可以省略 value,如果是其它名称,必须以 key-value 的形式
注解的使用场景
源码
APT,在编译期能够获取注解与注解声明的类包括类中所有成员信息,一般用于生成额外的辅助类。 javac采集所有的注解信息 -> Element -> 注解处理程序
代码检查
IDE 插件负责检查
@IntDef({0,1,2,3,4,5,6})
@Target({ElementType.FIELD,ElementType.PARAMETER})
@Retention(RetentionPolicy.SOURCE)
public @interface WeekDay {
}
//限定 setWeekDay 方法 和 day 属性的范围是0~6
@WeekDay int day;
void setWeekDay(@WeekDay int day){
this.day = day;
}
字节码
字节码增强,在编译出 Class 后,通过修改 Class 数据以实现修改代码逻辑目的。对于是否需要修改的区分或者修改为不同逻辑的判断可以使用注解。
反射
在程序运行期间,通过反射技术动态获取注解与其元素,从而完成不同的逻辑判定。例如 gson 中的 TypeToken