注释不是从接口方法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()); }