有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java是类级注释的定义类加载器始终是该类的初始类加载器的父级?

假设如下:

@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()));

共 (1) 个答案

  1. # 1 楼答案

    简单的回答是:没有

    答案很长

    RetentionPolicy.RUNTIME注释仅可通过反射API进行发现。这样做是为了确保注释和注释代码之间的松散耦合。根据this bug reportgetAnnotations()必须跳过未知注释,这意味着可以使用类加载器无法识别的注释。所讨论的实际Java代码的行为证实了这一假设

    这种行为有两个含义:

    1. 所有无法识别的注释(例如不在类路径中的注释)都变为“不可见”
    2. 为了显示它们,类必须由另一个可以同时访问类型和注释的类加载器完全重新加载

    例如,如果在加载someClasssomepkg.SomeAnnotation不在类路径中,这将不起作用:

    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"));