@Inherited
使用范围:注解类型(Annotation Type)
生命周期:运行时
如果某个注解上有@Inherited
注解,当查找该类型的注解时,会先查找目标类型是否存在注解,如果有,直接返回;否则,继续在父类上寻找注解,停止的条件为在父类上找到该类型的注解或者父类为Object
类型。
需要注意的是:Java只会搜索父类的注解而不会搜索其实现的接口
@Target
表示某个注解可注解的元素的集合
使用范围:注解类型(Annotation Type)
生命周期:运行时
ElementType
名称 | 描述 |
---|---|
TYPE | 类、接口(包含注解类型)、枚举定义 |
FIELD | 类中定义的静态成员、非静态成员以及枚举类型中的常量 |
METHOD | 普通方法(不包含构造方法) |
PARAMETER | 方法参数(包含构造方法参数) |
CONSTRUCTOR | 构造方法 |
LOCAL_VARIABLE | 局部变量声明 |
ANNOTATION_TYPE | 注解类型 |
PACKAGE | 用于package-info.java |
TYPE_USE | 用于类型定义、方法参数声明、成员变量定义、存在返回类型的函数声明、局部变量定义 |
Example
LOCAL_VARIABLE
@Target(ElementType.LOCAL_VARIABLE)
@Retention(RetentionPolicy.RUNTIME)
@interface TestLocalVar {
}
public class TestLocalVarClass {
private Integer f;
public TestLocalVarClass(Integer b) throws IOException {
@TestLocalVar
Integer a = 0;
try (@TestLocalVar InputStream in = Files.newInputStream(Paths.get(""))){
}
for (@TestLocalVar int i = 0; i < 10; ++i ){
}
}
}
TYPE_USE
@Target(ElementType.TYPE_USE)
@Retention(RetentionPolicy.RUNTIME)
@interface TypeUse {
}
@TypeUse
static class TypeUserTestClass {
private Integer a;
private String b;
@TypeUse
private TypeUserTestClass test;
@TypeUse
public Object returnTest(@TypeUse Integer a) {
@TypeUse
Integer b = 1;
return null;
}
}
@Target({})
的理解
@Target({})
@interface TestAnno {
}
@Retention(RetentionPolicy.RUNTIME)
@interface Composite {
TestAnno[] value();
}
@Composite(@TestAnno)
static class TestClass { }
这种情况下,我们只能将该注解用于作为注解的成员方法类型使用,但不能注解在其他可注解元素之上。
@Retention
表示注解的周期
使用范围:注解类型(Annotation Type)
生命周期:运行时
RetentionPolicy
名称 | 描述 |
---|---|
SOURCE | 该注解将会被编译器丢弃,可以被AnnotationProcessor处理 |
CLASS | 注解会在编译成类元信息存放在类文件中,但不会加载到Java运行时,无法通过反射获取 |
RUNTIME | 注解会在编译成类元信息存放在类文件中,同时会加载到Java运行时,可以通过反射获取 |
我们如果需要写运行时注解解析器,一定要记得将注解标记为@Retention(RUNTIME)
@Documented
使用范围:注解类型(Annotation Type)
生命周期:运行时
表示是否需要为注解生成javadoc
当我们不使用@Documented
时,我们尝试使用idea查看其document时,会发现文档是空的;但如果加上@Documented
,idea就会为其生成相应的文档