[英]How do Java method annotations work in conjunction with method overriding?
I have a parent class Parent
and a child class Child
, defined thus:我有一个 parent class
Parent
和一个 child class Child
,定义如下:
class Parent {
@MyAnnotation("hello")
void foo() {
// implementation irrelevant
}
}
class Child extends Parent {
@Override
foo() {
// implementation irrelevant
}
}
If I obtain a Method
reference to Child::foo
, will childFoo.getAnnotation(MyAnnotation.class)
give me @MyAnnotation
?如果我获得对
Child::foo
的Method
引用, childFoo.getAnnotation(MyAnnotation.class)
会给我@MyAnnotation
吗? Or will it be null
?还是
null
?
I'm interested more generally in how or whether annotation works with Java inheritance.我对注释如何或是否与 Java inheritance 一起工作更感兴趣。
Copied verbatim from http://www.eclipse.org/aspectj/doc/released/adk15notebook/annotations.html#annotation-inheritance :从http://www.eclipse.org/aspectj/doc/released/adk15notebook/annotations.html#annotation-inheritance逐字复制:
Annotation Inheritance
批注Inheritance
It is important to understand the rules relating to inheritance of annotations, as these have a bearing on join point matching based on the presence or absence of annotations.
了解与注释 inheritance 有关的规则很重要,因为这些规则与基于注释存在与否的连接点匹配有关。
By default annotations are not inherited.
默认情况下,注释不会被继承。 Given the following program
给定以下程序
@MyAnnotation
class Super {
@Oneway public void foo() {}
}
class Sub extends Super {
public void foo() {}
}
Then
Sub
does not have theMyAnnotation
annotation, andSub.foo()
is not an@Oneway
method, despite the fact that it overridesSuper.foo()
which is.然后
Sub
没有MyAnnotation
注释,并且Sub.foo()
不是@Oneway
方法,尽管它覆盖Super.foo()
这是。If an annotation type has the meta-annotation
@Inherited
then an annotation of that type on a class will cause the annotation to be inherited by sub-classes.如果注释类型具有元注释
@Inherited
,则 class 上该类型的注释将导致该注释被子类继承。 So, in the example above, if theMyAnnotation
type had the@Inherited
attribute, thenSub
would have theMyAnnotation
annotation.因此,在上面的示例中,如果
MyAnnotation
类型具有@Inherited
属性,则Sub
将具有MyAnnotation
注释。
@Inherited
annotations are not inherited when used to annotate anything other than a type.@Inherited
注释在用于注释除类型以外的任何内容时不会被继承。 A type that implements one or more interfaces never inherits any annotations from the interfaces it implements.实现一个或多个接口的类型永远不会从它实现的接口继承任何注释。
You found your answer already: there is no provision for method-annotation inheritance in the JDK.您已经找到了答案:JDK 中没有方法注释 inheritance 的规定。
But climbing the super-class chain in search of annotated methods is also easy to implement:但是攀登超类链以搜索带注释的方法也很容易实现:
/**
* 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);
}
Using Spring Core you can resolve with使用 Spring 核心你可以解决
While the answer to the question as asked is that Java's Method.getAnnotation()
does not consider overridden methods, sometimes it is useful to find these annotations.虽然所问问题的答案是 Java 的
Method.getAnnotation()
不考虑覆盖的方法,但有时找到这些注释很有用。 Here is a more complete version of Saintali's answer that I'm currently using:这是我目前正在使用的 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;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.