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

前端 未结 1 1838
刺人心
刺人心 2020-12-16 18:01

Suppose the following:

@SomeAnnotation
public interface Foo {
}

I would like to know if it is always the case that either the defining clas

相关标签:
1条回答
  • 2020-12-16 18:15

    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"));
    
    0 讨论(0)
提交回复
热议问题