Java 메서드 주석은 메서드 재정의와 함께 어떻게 작동합니까?
부모 클래스 Parent
와 자식 클래스 Child
가 있습니다.
class Parent {
@MyAnnotation("hello")
void foo() {
// implementation irrelevant
}
}
class Child {
@Override
foo() {
// implementation irrelevant
}
}
내가 얻을 수있는 경우 Method
에 대한 참조를 Child::foo
, 것이다 childFoo.getAnnotation(MyAnnotation.class)
줘 @MyAnnotation
? 아니면 그럴까요 null
?
나는 주석이 Java 상속과 어떻게 작동하는지 여부에 더 일반적으로 관심이 있습니다.
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);
}
Spring Core를 사용하여 해결할 수 있습니다.
질문에 대한 대답은 Java가 Method.getAnnotation()
재정의 된 메서드를 고려하지 않는다는 것이지만 때로는 이러한 주석을 찾는 것이 유용합니다. 현재 사용중인 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;
}
}
'Programing' 카테고리의 다른 글
NUnit 3.0 및 Assert.Throws (0) | 2020.11.25 |
---|---|
jQuery를 사용하여 ASP.NET 웹 서비스를 호출하는 방법은 무엇입니까? (0) | 2020.11.25 |
앱을 다운로드하고 설치할 때 기기에서 .apk 파일을 어디에서 찾을 수 있습니까? (0) | 2020.11.25 |
색상 및 모양에 대한 범례를 하나의 범례로 결합 (0) | 2020.11.25 |
CSS 키 프레임 애니메이션 CPU 사용량이 높습니다. 이렇게해야합니까? (0) | 2020.11.25 |