Java Annotation Retention(可见性)

 注解有三个可见性:

源码可见(SOURCE)

 

字节码可见(CLASS)

 

运行时可见(RUNTIME)

 

这三个可见性是层层递增的,也就是说运行时可见的注解在前两种状态都是可见的。

下面来验证说明下

 

三个注解源码:

 

TestAnnoRetentionSource:

@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.FIELD)
public @interface TestAnnoRetentionSource {

}

 

 TestAnnoRetentionClass: 

@Retention(RetentionPolicy.CLASS)
@Target(ElementType.FIELD)
public @interface TestAnnoRetentionClass {

}

 

 TestAnnoRetentionRuntime: 

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface TestAnnoRetentionRuntime {

}

 

测试类如下:

public class AnnotationTest {
	@TestAnnoRetentionSource
	public int sourceVisible;
	@TestAnnoRetentionClass
	public int classVisible;
	@TestAnnoRetentionRuntime
	public int runtimeVisible;

	public static void main(String[] args) {
		Class<AnnotationTest> clazz = AnnotationTest.class;
		for (Field each : clazz.getFields()) {
			System.out.println(each.getName() + ":");
			for (Annotation anno : each.getAnnotations()) {
				System.out.println("\t" + anno.annotationType().getName());
			}
			System.out.println();
		}
	}
}

 

可以看到三个注解类分别对应三个可见性,并且测试类中三个实例变量也分别用对应的注解修饰。

测试类输入是:

 

sourceVisible:

classVisible:

runtimeVisible:
	cn.teaey.test.annotation.TestAnnoRetentionRuntime

 

到现在我们能知道,只有课件性为Runtime的注解在我们代码运行的时候能够获取到。

 

再用javap命令查看下测试类的字节码(class)文件

命令:javap -verbose AnnotationTest

输入(部分):

 

1. const #5 = Asciz        sourceVisible;

2. const #7 = Asciz        classVisible;

3. const #8 = Asciz        RuntimeInvisibleAnnotations;

4. const #9 = Asciz        Lcn/teaey/test/annotation/TestAnnoRetentionClass;;

5. const #10 = Asciz       runtimeVisible;

6. const #11 = Asciz       RuntimeVisibleAnnotations;

7. const #12 = Asciz       Lcn/teaey/test/annotation/TestAnnoRetentionRuntime;;

 

第1行能看出,sourceVisible在class字节码中没有任何注解修饰

第2、3、4行可以看出,classVisible变量被一个RuntimeInvisibleAnnotations运行时不可见的注解TestAnnoRetentionClass修饰

第5、6、7行说明,runtimeVisible变量被一个RuntimeVisibleAnnotations运行时可见的注解TestAnnoRetentionRuntime修饰。

 

总结:

SOURCE:只存在于JAVA源码(.java)文件中

CLASS:存在于JAVA源码和字节码(.class)文件中

RUNTIME:在源码、字节码中可见,同时可以在代码中访问

你可能感兴趣的:(Java Annotation)