携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第七天,点击查看活动详情
注解
我们在之前两章节中学习了标准注解(内置注解)和元注解,我们接下来开始自定义注解
定义注解
1. 基本定义
定义新的注解类型使用关键字@interface,这与定义一个接口很像,如下所示:
public @interface CustomAnnotation{
...
}
定义注解完成之后,我们就可以在程序中使用该注解:
@CustomAnnotation
public class AnnotationTest{
...
}
2. 定义成员变量
注解只有成员变量,没有方法。注解的成员变量在注解定义中以“无参的方法”的形式来声明,其“方法名”定义了该成员变量的名字,其返回值定义了该成员的变量类型
我们来看一下实例:
public @interface UserTest{
//成员变量以变量名的无参方法来声明
String name();
int age();
}
上面的代码中定义了两个成员变量,这两个成员变量以无参方法的形式来定义。定义了成员变量以后,我们就可以使用该注解时就应该为该注解的成员变量指定值
我们接上面的注解来看一下实例:
public class TestUserTest{
@UserTest(name = "zhangsan",age=18)
public void dosome(){
...
}
}
当然我们也可以在声明注解的成员变量的时候也添加默认值,添加默认值的时候需要使用关键字default来定义,如下代码所示:
public @interface UserTest{
String name() default "zhangsan";
int age() default 18;
}
当我们注解定义了默认值的时候,我们在使用该注解的时候,不指定成员变量的值的时候,就会直接使用默认值。如下代码所示:
public class TestUserTest{
@UserTest()
public void dosome(){
...
}
}
3. 定义运行时注解
可以直接使用@Retention来设定注解的保留策略。@Retention已经在中已经详细讲解过,我们在简单回顾一下,@Retention有三个策略,这三个策略的声明周期长度为 RetentionPolicy.SOURCE< RetentionPolicy.CLASS < RetentionPolicy.RUNTIME。生命周期短的能起到作用的地方,声明周期长的也一定能起到作用。一般如果需要在运行时去动态获取注解信息,那只用用 RetentionPolicy.RUNTIME,如果要在编译时进行一些预处理操作,比如生成一些辅助代码,就用RetentionPolicy.CLASS;如果只是做一些检查的操作,比如@Verride和@SuppressWarnings,则可以选用RetentionPolicy.SOURCE.当设定为RetentionPolicy.RUNTIME时,这个注解就是运行时注解,如下所示:
@Retention(RetentionPolicy.SOURCE)
public @interface UserTest{
String name() default "zhangsan";
int age() default 18;
}
4. 定义编译时注解
同样的,如果讲@Retention的保留策略设定为RetentionPolicy.CLASS,这个注解就是编译时注解,如下所示:
@Retention(RetentionPolicy.CLASS)
public @interface UserTest{
String name() default "zhangsan";
int age() default 18;
}
编译处理器
如果没有处理注解的工具,那么注解也不会有什么大作用。对于不同的注解又有不用的注解处理器。虽然注解处理器的编写会千变万化,但是其也有处理标准,比如:针对运行时注解会采用反射机制处理,针对编译时注解会采用AbstractProcessor来处理。接下来就针对前面降到的运行时注解和编译时注解来编写处理器
1. 运行时注解处理器
处理运行时注解需要用到反射机制。首先我们要定义运行时注解,如下所示:
@Documented
@Target
@Retention(RUNTIME)
public @interface GET{
String value() default "";
}
上面代码就是Retofit中定义@GET注解。其定义了@Target(METHOD),意味着GET注解应用于方法,接下来我们来看看如何使用该注解,如下所示:
public class Test{
@GET(value ="https://ip/test")
public String getTest(){
return;
}
}