假设以下内容:
@SomeAnnotation
public interface Foo {
}
我想知道SomeAnnotation
的定义类加载器是否等于Foo
的初始类加载器的父类。
我看过JVMS v8 section 5.3。但我不确定这里适用的是什么。第5.3.4节讨论了加载约束,但它们似乎不适用于注释。
我问的问题是因为这样的代码:
Class<?> fooClass = //will in some way obtain a reference to class Foo
fooClass.getAnnotation(SomeAnnotation.class);
将在不同的类加载器存在时失败。我知道我可以使用getAnnotations并在结果数组中搜索类名等于SomeAnnotation
的元素。但是我想知道以下内容是否也会起作用:
Class<?> fooClass = //will in some way obtain a reference to class Foo
fooClass.getAnnotation((Class<? extends Annotation>) fooClass
.getClassLoader().loadClass(SomeAnnotation.class.getName()));
答案 0 :(得分:8)
答案简短:没有
答案很长。
RetentionPolicy.RUNTIME
注释仅可通过反射API进行发现。这样做是为了确保注释和带注释的代码之间的松散耦合。根据{{3}},getAnnotations()
必须跳过未知的注释,这意味着可以使用类加载器无法识别的注释。所讨论的真实Java代码的行为this bug report验证了这种假设。
这种行为有两个含义:
例如,如果加载somepkg.SomeAnnotation
时someClass
不在类路径中,则无效:
Class<?> someClass = ....
URL [] classPathWithAnnotations = ....
ClassLoader cl = new URLClassLoader(classPathWithAnnotations);
Annotation a = someClass.getAnnotation(cl.loadClass("somepkg.SomeAnnotation"));
// a will be null
但这会:
Class<?> someClass = ....
URL [] classPathWithSomeClassAndAnnotations = ....
ClassLoader cl = new URLClassLoader(classPathWithSomeClassAndAnnotations, null);
Annotation a = cl.loadClass(someClass.getName()).getAnnotation(cl.loadClass("somepkg.SomeAnnotation"));