Programing

Java 메서드 주석은 메서드 재정의와 함께 어떻게 작동합니까?

lottogame 2020. 11. 25. 07:29
반응형

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를 사용하여 해결할 수 있습니다.

AnnotationUtils.java


질문에 대한 대답은 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;
    }
}

참고 URL : https://stackoverflow.com/questions/10082619/how-do-java-method-annotations-work-in-conjunction-with-method-overriding

반응형