java - @Inherited注解没有被继承

标签 java inheritance annotations

我有一个SubClass和一个SuperClass,以及一个注释DocAnnotation。我需要调用 SubClass.foo() 来获取 SubClassSuperClass 中的所有类注释。类的定义如下:

父类(super class)

package Code

import Annotations.DocAnnotation;
import java.util.Arrays;

@DocAnnotation("Super Annotation")
public class SuperClass {

    public void foo() {
        System.out.println(Arrays.toString(this.getClass().getAnnotations()));
        System.out.println(Arrays.toString(this.getClass().getDeclaredAnnotations()));
    }
}

子类

package Code;

import Annotations.DocAnnotation;

@DocAnnotation("Sub Annotation")
public class SubClass extends SuperClass{
}

文档注释

package Annotations;

import java.lang.annotation.Inherited;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(DocAnnotations.class)
public @interface DocAnnotation {
    String value();
}

运行 SubClass.foo 我希望看到 "Super Annotation""Sub Annotation" 但我只看到 [@Annotations.DocAnnotation(value =子注释)]。我是否误解了 @inherited 的作用,或者我做错了什么?

<小时/>

编辑:

将注释 @DocAnnotation("Super Annotation") 添加到 SubClass 后(与 SuperClass 中的注释相同),它实际上显示上升两次,一次用于在 SubClass 中使用,一次用于在 SuperClass 中使用!现在我几乎可以肯定我误解了一些东西......

最佳答案

这似乎是预期的行为,或者至少指定它以这种方式工作( doc ):

If [...] the user queries the annotation type on a class declaration, and the class declaration has no annotation for this type, then the class's superclass will automatically be queried for the annotation type.

换句话说,由于SubClass已经用@DocAnnotation注释,所以不会查询父类(super class)。

经过进一步检查,该行为似乎有点奇怪,尤其是在尝试包含注释类型的存在之后。我想出了以下示例来说明这一点( link ):

import java.lang.annotation.*;
import java.util.*;

@Inherited
@Repeatable(Container.class)
@Retention(RetentionPolicy.RUNTIME)
@interface Ann {
    String value();
}

@Inherited
@Retention(RetentionPolicy.RUNTIME)
@interface Container {
    Ann[] value();
}

// Basic case. Result is that
// only @Ann("2") is present on
// ExhibitASub.
@Ann("1")
class ExhibitASuper {
}
@Ann("2")
class ExhibitASub extends ExhibitASuper {
}

// Because this case results in the
// @Container being present on ExhibitBSuper,
// rather than @Ann, all three annotations
// end up appearing on ExhibitBSub.
@Ann("1")
@Ann("2")
class ExhibitBSuper {
}
@Ann("3")
class ExhibitBSub extends ExhibitBSuper {
}

// Similar to the preceding case, by
// forcing the use of @Container, both
// annotations are present on ExhibitCSub.
@Container(@Ann("1"))
class ExhibitCSuper {
}
@Ann("2")
class ExhibitCSub extends ExhibitCSuper {
}

// Yet when we force both to use @Container,
// only @Container(@Ann("2")) is present on
// ExhibitDSub.
@Container(@Ann("1"))
class ExhibitDSuper {
}
@Container(@Ann("2"))
class ExhibitDSub extends ExhibitDSuper {
}

class Main {
    public static void main(String[] args) {
        for (Class<?> cls : Arrays.asList(ExhibitASub.class,
                                          ExhibitBSub.class,
                                          ExhibitCSub.class,
                                          ExhibitDSub.class)) {
            System.out.printf("%s:%n", cls);
            for (Annotation ann : cls.getAnnotations()) {
                System.out.printf("    %s%n", ann);
            }

            System.out.println();
        }
    }
}

其输出如下:

class ExhibitASub:
    @Ann(value=2)

class ExhibitBSub:
    @Container(value=[@Ann(value=1), @Ann(value=2)])
    @Ann(value=3)

class ExhibitCSub:
    @Container(value=[@Ann(value=1)])
    @Ann(value=2)

class ExhibitDSub:
    @Container(value=[@Ann(value=2)])

请注意,对于 B 和 C,我们可以看到父类(super class)和子类上的注释。据推测,这是因为(严格意义上)父类(super class)上存在的注释与子类上存在的注释属于不同类型。请注意,对于 D,我们返回只看到子类注释,因为两个类都使用容器类型。

显式使用包含注释类型可能是某些情况下的解决方法,但由于情况 D,它不是通用解决方案。

明天我可能会为此提交一份错误报告,因为这似乎是非常不可取的。由于 @Inherited 早于 @Repeatable,因此此行为可能来自以前的版本,而这种情况不会发生。

关于java - @Inherited注解没有被继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46087372/

相关文章:

python - 如何使 python 对象可通过 numpy.array() 调用

java - 注释参数 - String[] 类型参数设置为字符串文字

java - 获取单个切入点中不同注释的参数

java - 如何从java在matlab中加载图像

c++ - 私有(private)/保护变量 "error: within this context"

java - 唯一ID生成算法

c++ - 通过 Derived::f2() 调用 f1() 时调用了谁的函数?

java - 是否可以在 Eclipse 中查看注释的类型层次结构?

java - 我可以从 Java 文件构建结果集吗?

java - 当我当前页面的 html 通过 Jquery 传递到托管 bean 时,primefaces remoteCommand 标记不起作用