Is the defining classloader of a class level annotation always a parent of the initiating classloader of that class?

时光总嘲笑我的痴心妄想 提交于 2019-11-29 03:55:10
anttix

The short answer: no

The long answer.

RetentionPolicy.RUNTIME annotations are available for discovery via the reflection API only. This is done to ensure loose coupling between annotations and annotated code. According to this bug report, getAnnotations() must skip unknown annotations which implies that it's ok to have annotations that are not recognized by the classloader. The behavior of real Java code discussed here validates that assumption.

This behavior has two implications:

  1. All unrecognized annotations (e.g. the ones not in classpath) become "invisible"
  2. In order to reveal them, the class must be completely reloaded by a different classloader that has access to both, the type and annotations.

For example if somepkg.SomeAnnotation was not in classpath when someClass was loaded, this will not work:

Class<?> someClass = ....
URL [] classPathWithAnnotations = ....

ClassLoader cl = new URLClassLoader(classPathWithAnnotations);
Annotation a = someClass.getAnnotation(cl.loadClass("somepkg.SomeAnnotation"));
// a will be null

But this will:

Class<?> someClass = ....
URL [] classPathWithSomeClassAndAnnotations = ....

ClassLoader cl = new URLClassLoader(classPathWithSomeClassAndAnnotations, null);
Annotation a = cl.loadClass(someClass.getName()).getAnnotation(cl.loadClass("somepkg.SomeAnnotation"));
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!