Java 方法注释如何与方法重写一起工作?

我有一个父类 Parent和一个子类 Child,定义如下:

class Parent {
@MyAnnotation("hello")
void foo() {
// implementation irrelevant
}
}
class Child extends Parent {
@Override
foo() {
// implementation irrelevant
}
}

如果我获得一个 Method参考 Child::foo,将 childFoo.getAnnotation(MyAnnotation.class)给我 @MyAnnotation? 或将它是 null

我更感兴趣的是注释如何或是否与 Java 继承一起工作。

39655 次浏览

http://www.eclipse.org/aspectj/doc/released/adk15notebook/annotations.html#annotation-inheritance逐字复制:

注释继承

理解与注释的继承有关的规则很重要,因为这些规则与基于是否存在注释的连接点匹配有关。

默认情况下,不会继承注释

        @MyAnnotation
class Super {
@Oneway public void foo() {}
}


class Sub extends Super {
public void foo() {}
}

那么 Sub没有 MyAnnotation注释,而且 Sub.foo()也不是 @Oneway方法,尽管它覆盖了 Super.foo()

如果一个注释类型具有元注释 @Inherited,那么类上该类型的注释将导致该注释被子类继承。因此,在上面的示例中,如果 MyAnnotation类型具有 @Inherited属性,那么 Sub将具有 MyAnnotation注释。

@Inherited注释在用于注释类型以外的任何内容时不会继承。实现一个或多个接口的类型永远不会从其实现的接口继承任何注释。

您已经找到了答案: JDK 中没有关于方法注释继承的规定。

但是,攀爬超类链以寻找带注释的方法也很容易实现:

/**
* 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);
}

虽然问题的答案是 Java 的 Method.getAnnotation()不考虑重写方法,但是有时候找到这些注释是有用的。以下是我目前正在使用的圣塔利回答的更完整版本:

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 可以解决

注释工具.java