Java 注释不是从接口方法继承的

Java 注释不是从接口方法继承的,java,annotations,Java,Annotations,我有一个带注释方法的接口。注释标记为@Inherited,因此我希望实现者继承它。然而,情况并非如此: 代码: 上述代码打印: 公共抽象void annotations.TestInterface.m():[@annotations.TestAnnotation()] 公共void注释。示例$1.m():[] 因此,问题是为什么obj.m()没有@TestAnnotation,尽管它实现了一个标记为@TestAnnotation的方法,它是@Inherited?从java.lang.annota

我有一个带注释方法的接口。注释标记为
@Inherited
,因此我希望实现者继承它。然而,情况并非如此:

代码:

上述代码打印:

公共抽象void annotations.TestInterface.m():[@annotations.TestAnnotation()]

公共void注释。示例$1.m():[]

因此,问题是为什么
obj.m()
没有
@TestAnnotation
,尽管它实现了一个标记为
@TestAnnotation
的方法,它是
@Inherited

java.lang.annotation.Inherited

请注意,如果已注释的 类型用于注释除类以外的任何内容。还请注意 此元注释只会导致从中继承注释 超类;已实现接口上的注释无效

从javadoc:

请注意,如果注释类型用于注释类以外的任何内容,则此元注释类型无效。还要注意,这个元注释只会导致注释从超类继承;已实现接口上的注释无效`


总之,它不适用于方法。

或者,您可以使用反射来派生相同的信息。方法
printMethodAnnotations
可以重写为:

private static void printMethodAnnotations(Method m) {
    Class<?> methodDeclaredKlass = m.getDeclaringClass();
    List<Class<?>> interfases = org.apache.commons.lang3.ClassUtils.getAllInterfaces(methodDeclaredKlass);
    List<Annotation> annotations = new ArrayList<>();
    annotations.addAll(Arrays.asList(m.getAnnotations()));
    for (Class<?> interfase : interfases) {
        for (Method interfaseMethod : interfase.getMethods()) {
            if (areMethodsEqual(interfaseMethod, m)) {
                annotations.addAll(Arrays.asList(interfaseMethod.getAnnotations()));
                continue;
            }
        }
    }
    System.out.println(m + "*: " + annotations);
}

private static boolean areMethodsEqual(Method m1, Method m2) {
    // return type, Modifiers are not required to check, if they are not appropriate match then it will be a compile
    // time error. This needs enhancements for Generic types parameter ?
    return m1.getName().equals(m2.getName()) && Arrays.equals(m1.getParameterTypes(), m2.getParameterTypes());
}
私有静态void printMethodAnnotations(方法m){
类methodDeclaredKlass=m.getDeclaringClass();

ListWoa,同时回答=)我两个都投了赞成票,但只接受了一个答案。对不起,@Gilberto,Abhinav快了一点:)没问题,我们是来帮忙的;-)答案就在@AbhinavSakar和@Gilberto指出的
@Inherited
的文档中。很抱歉。我做了很多实验ut忽略了显而易见的——文档。顺便问一下,你知道这样一个设计决策的原因是什么吗?我希望元注释也能在方法上起作用。没问题,令人惊讶的是,超类与超接口的处理方式不同。这就是为什么一些框架(如Spring)会这样做的原因随附的反射实用程序也可以查询超级接口。只是出于好奇,Spring中的哪个实用程序?谢谢。对我有用。但我可以使用Spring core的注释实用程序找到相同的功能。下面是maven dep
private static void printMethodAnnotations(Method m) {
    Class<?> methodDeclaredKlass = m.getDeclaringClass();
    List<Class<?>> interfases = org.apache.commons.lang3.ClassUtils.getAllInterfaces(methodDeclaredKlass);
    List<Annotation> annotations = new ArrayList<>();
    annotations.addAll(Arrays.asList(m.getAnnotations()));
    for (Class<?> interfase : interfases) {
        for (Method interfaseMethod : interfase.getMethods()) {
            if (areMethodsEqual(interfaseMethod, m)) {
                annotations.addAll(Arrays.asList(interfaseMethod.getAnnotations()));
                continue;
            }
        }
    }
    System.out.println(m + "*: " + annotations);
}

private static boolean areMethodsEqual(Method m1, Method m2) {
    // return type, Modifiers are not required to check, if they are not appropriate match then it will be a compile
    // time error. This needs enhancements for Generic types parameter ?
    return m1.getName().equals(m2.getName()) && Arrays.equals(m1.getParameterTypes(), m2.getParameterTypes());
}