Java方法注释如何与方法重写一起使用?
我有一个父类和一个子类Child
,这样定义:
class Parent { @MyAnnotation("hello") void foo() { // implementation irrelevant } } class Child { @Override foo() { // implementation irrelevant } }
如果我得到一个Method
引用到Child::foo
,将childFoo.getAnnotation(MyAnnotation.class)
给我@MyAnnotation
? 或将它为null
?
我更感兴趣的是如何或者注释是否与Javainheritance一起工作。
注释inheritance
了解与注释inheritance有关的规则很重要,因为这些规则会根据注释的存在或不存在来影响连接点匹配。
默认情况下,注释不会被inheritance。 给定以下程序
@MyAnnotation class Super { @Oneway public void foo() {} } class Sub extends Super { public void foo() {} }
然后
Sub
没有MyAnnotation
注解,而Sub.foo()
不是@Oneway
方法,尽pipe它覆盖了Super.foo()
这个事实。如果注释types具有元注释
@Inherited
那么在类上注释该types将导致注释@Inherited
类inheritance。 所以,在上面的示例中,如果MyAnnotation
types具有@Inherited
属性,则Sub
将具有MyAnnotation
注释。用于注释除types以外的其他注释时,不会inheritance
@Inherited
注释。 实现一个或多个接口的types永远不会从它实现的接口inheritance任何注释。
您已经find了答案:JDK中没有提供方法注释inheritance的规定。
但是,寻找注解方法的超级链,也很容易实现:
/** * Climbs the super-class chain to find the first method with the given signature which is * annotated with the given annotation. * * @return A method of the requested signature, applicable to all instances of the given * class, and annotated with the required annotation * @throws NoSuchMethodException If no method was found that matches this description */ public Method getAnnotatedMethod(Class<? extends Annotation> annotation, Class c, String methodName, Class... parameterTypes) throws NoSuchMethodException { Method method = c.getMethod(methodName, parameterTypes); if (method.isAnnotationPresent(annotation)) { return method; } return getAnnotatedMethod(annotation, c.getSuperclass(), methodName, parameterTypes); }
尽pipe问题的答案是Java的Method.getAnnotation()
不考虑重写的方法,但有时候find这些注释是很有用的。 这里是我目前使用的较为完整的Saintali答案:
public static <A extends Annotation> A getInheritedAnnotation( Class<A> annotationClass, AnnotatedElement element) { A annotation = element.getAnnotation(annotationClass); if (annotation == null && element instanceof Method) annotation = getOverriddenAnnotation(annotationClass, (Method) element); return annotation; } private static <A extends Annotation> A getOverriddenAnnotation( Class<A> annotationClass, Method method) { final Class<?> methodClass = method.getDeclaringClass(); final String name = method.getName(); final Class<?>[] params = method.getParameterTypes(); // prioritize all superclasses over all interfaces final Class<?> superclass = methodClass.getSuperclass(); if (superclass != null) { final A annotation = getOverriddenAnnotationFrom(annotationClass, superclass, name, params); if (annotation != null) return annotation; } // depth-first search over interface hierarchy for (final Class<?> intf : methodClass.getInterfaces()) { final A annotation = getOverriddenAnnotationFrom(annotationClass, intf, name, params); if (annotation != null) return annotation; } return null; } private static <A extends Annotation> A getOverriddenAnnotationFrom( Class<A> annotationClass, Class<?> searchClass, String name, Class<?>[] params) { try { final Method method = searchClass.getMethod(name, params); final A annotation = method.getAnnotation(annotationClass); if (annotation != null) return annotation; return getOverriddenAnnotation(annotationClass, method); } catch (final NoSuchMethodException e) { return null; } }
使用Spring Core,您可以使用
AnnotationUtils.java