注释不是从接口方法inheritance的

我有一个带注释方法的接口。 注释用@Inherited标记,所以我希望实现者inheritance它。 但事实并非如此:

码:

 import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.reflect.Method; import java.util.Arrays; public class Example { public static void main(String[] args) throws SecurityException, NoSuchMethodException { TestInterface obj = new TestInterface() { @Override public void m() {} }; printMethodAnnotations(TestInterface.class.getMethod("m")); printMethodAnnotations(obj.getClass().getMethod("m")); } private static void printMethodAnnotations(Method m) { System.out.println(m + ": " + Arrays.toString(m.getAnnotations())); } } interface TestInterface { @TestAnnotation public void m(); } @Retention(RetentionPolicy.RUNTIME) @Inherited @interface TestAnnotation {} 

上面的代码打印:

public abstract void annotations.TestInterface.m():[@ annotations.TestAnnotation()]

public void annotations.Example $ 1.m():[]

所以问题是为什么obj.m()具有@TestAnnotation尽管它实现了一个用@TestAnnotation标记的@Inherited

java.lang.annotation.Inherited的javadocs :

请注意,如果使用带注释的类型来注释除类之外的任何内容,则此元注释类型不起作用。 另请注意,此元注释仅导致注释从超类inheritance; 已实现接口上的注释无效。

来自@Inherited javadoc:

请注意,如果使用带注释的类型来注释除类之外的任何内容,则此元注释类型不起作用。 另请注意,此元注释仅导致注释从超类inheritance; 已实现接口上的注释无效

总之,它不适用于方法。

或者,您可以使用reflection来获取相同的信息。 printMethodAnnotations方法可以重写为:

 private static void printMethodAnnotations(Method m) { Class methodDeclaredKlass = m.getDeclaringClass(); List> interfases = org.apache.commons.lang3.ClassUtils.getAllInterfaces(methodDeclaredKlass); List 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()); }