我们知道注解的RetentionPolicy有三种类型:
(1)RetentionPolicy.SOURCE:只在编译时能被感知,不会在class文件出现
(2)RetentionPolicy.CLASS:会被编译进class文件,但不会在虚拟机运行时感知
(3)RetentionPolicy.RUNTIME:是在运行时也可以被感知到
RetentionPolicy.SOURCE和RetentionPolicy.RUNTIME都比较好理解,接触的也比较多。比如lombok的注解基本都是RetentionPolicy.SOURCE,用于在编译成class文件时动态生成代码,在class文件看不到对应注解存在。而我们大部分写的应用程序注解则大部分是PetentionPolicy.RUNTIME,比如使用Spring AOP时定义运行时注解,提供额外的切面信息。
但RetentionPolicy.CLASS的就很少了,那么它是做什么的呢?
首先我们来自定义一个RetentionPolicy.CLASS的注解:
这里定义了一个RetentionPolicyForClass注解类,在UserInfo类中使用,然后在尝试在运行时获取,我们发现idea会提示问题:Annotation 'RetentionPolicyForClass.class' is not retained for reflective access。注解不能通过反射获取,如果我们把RetentionPolicyForClass的Retention改成Runtime,test就能正常获取了,value是UserInfo类中设置的"userinfo"。实际运行,test返回的是null,确实在运行时获取注解信息。
然后查看UserInfo的class文件:注解信息在class文件中是存在的
所以我们在运行时是无法获取对应注解的信息的,那么它有什么用的。根据类加载的过程,加载需要经过加载,校验,准备,解析,初始化,使用,卸载,这七个步骤,在加载的时候就是把class文件加载到虚拟机,那么这时候虚拟机是能从class文件中感知到注解的存在的,那么就可以在连接阶段(校验,准备,解析)阶段根据信息进行一些操作,个人猜测大概率是给虚拟机底层使用的。如果大家有知道具体使用的,欢迎评论区交流^_^!