首先看一个自定义的注解:
1、自定义注解
public @interface MyAnnotation {
int age();
}
可见定义一个注解非常简单,只需要使用@interface关键字来定义即可。
同时我们可以看到,注解的内部可以定义变量,但是在定义变量之后必须加上括号()。
使用:
public class Test {
@MyAnnotation(age = 15) //使用自定义的注解
public static void main(String[] args) {
}
}
我们必须指明注解属性age的值,如果不想指明,而想给自定义注解设置一个默认值的话,可以这样写: int age() default 15; 使用default可以给自己的注解属性设置默认值。
public @interface MyAnnotation {
int age() default 15;
}
这样使用的时候即使不指明age的值也可以正常使用:
@MyAnnotation//使用自定义的注解
public static void main(String[] args) {
}
2、Retention和RetentionPolicy
Retention 翻译过来就是保留,滞留的意思,它也是一个注解,它可以用来表示我们的自定义注解的作用周期。
RetentionPolicy是一个枚举类型,它里面定义了注解的三种作用周期:源码期,CLASS文件时,运行时
public enum RetentionPolicy {
SOURCE,
CLASS,
RUNTIME;
private RetentionPolicy() {
}
}
SOURCE :此注解的信息只会记录在源文件中,编译时将被编译器丢弃,即此注解信息不回保留字编译好的class文件中。我们的自定义注解通常不会用到这种类型。
@Override和@SuppressWarnings就是此类注解,注解信息只能在源文件中出现。
CLASS:编译器将把注解记录在class文件中,但不会被加载到JVM中,如果我们自定义的注解没有声明作用范围,那么将默认是CLASS注解。这种注解被称为编译时注解。
RUNTIME:此注解的信息将会保留在源文件,class文件中,并且会在运行的时候加载到JVM中,因此这种注解可以通过反射读取。这种注解被称为运行时注解。
@Deprecated 就是此类注解,注解信息在执行时出现
我们很容易可以发现,一个注解的运行周期:RUNTIME>CLASS>SOURCE
总结一下就是:
如果要做一些源码的检查操作用SOURCE
如果要做一些预处理操作,比如生成代码就用CLASS,例如ButterKnife
如果要在运行时通过反射操作,动态的获取注解信息,就只能用RUNTIME
使用一下Retention:
@Retention(value = RetentionPolicy.RUNTIME)//表明我们的注解是一个运行时注解
public @interface MyAnnotation {
int age() default 15;
}
3、元注解
如上面的代码,像Retention这种用来表示注解的特殊注解,就被称为元注解。
其它的元注解还有:
@Target:表明注解使用的位置
@Document:表明注解将被包含在javadoc中
@Inherited:表明子类可以继承父类中的此注解
@Repeatable:java se8中引入的表明注解可以重复应用在同一个目标上
@Target的使用位置:@Target(ElementType.XXXX)
如果一个注解没有明确的指明使用的位置,则可以在任意的位置使用。
如果要让一个自定义的注解只能在指定的位置上使用,例如只能在类和方法上使用,就需要用到@Target
@Target明确的指出了一个注解的使用位置,在@Target中存在一个ElementType枚举类型变量,这个变量就是用来指定自定义注解的使用限制。
ElementType类定义了下面几个取值:
ElementType 类取值 | 含义 |
---|---|
TYPE | 只能用在接口、类、枚举类型上 |
FIELD | 只能用在字段、枚举的常量上 |
METHOD | 只能用在方法的声明上 |
PARAMETER | 只能用在参数的声明上 |
CONSTRUCTOR | 只能用在构造方法的声明上 |
LOCAL_VARIABLE | 只能用在局部变量的声明上 |
ANNOTATION_TYPE | 只能用在注释上 |
PACKAGE | 只能用在包的声明上 |
TYPE_PARAMETER | 类型,1.8以后添加 |
TYPE_USE | 类型,1.8以后添加 |
有了前两篇的知识后,我们就可以自己动手实现一个类似于butterknife的编译时注解框架啦 (^ ▽ ^)