查找被注释处理覆盖的方法

代码结构

假设我们有一个这样的结构:


class A {


    @AMethodAnnotation("my-data")

    public void myMethod() {


    }


}


@MyClassAnnotation

class B extends A {


    @Override

    public void myMethod() {


    }


}

我正在努力实现的目标

使用注释处理,我试图从AMethodAnnotation位于myMethodclass 内部方法上的注释中提取数据A。类B扩展了这个类并覆盖了它的方法myMethod。


扭曲的是我想要来自方法的数据,AMethodAnnotation如果它在里面的类有 annotation MyClassAnnotation。


我正在获取带有注释的类MyClassAnnotation并循环遍历 ,在enclosedElements那里我可以检查它是否有Override注释,但我不确定如何获取它覆盖的方法,因为那是AMethodAnnotation我想要的数据所在的位置。ExecutableElement似乎没有提供方法来获得这个。


for (Element classElement : roundEnv.getElementsAnnotatedWith(MyClassAnnotation.class)) {

    // Make sure it's a class

    if (classElement.getKind() != ElementKind.CLASS) {

        continue;

    }


    // Loop through methods inside class

    for (Element methodElement : classElement.getEnclosedElements()) {

        // Make sure the element is a method & has a @Path annotation

        if (methodElement.getKind() != ElementKind.METHOD) {

            continue;

        }


        // If method has @Override annotation do stuff


    }

}

问题

有没有办法获得对被覆盖的方法的引用?


有一种方法,您获取Bis的超类A并循环遍历enclosedElementsin A,然后您必须验证方法名称是否相同,以及参数是否相同且顺序相同。但是我发现这种方法需要大量检查,因此我的问题是是否有更好的方法。


SMILET
浏览 159回答 1
1回答

慕妹3242003

我根据评论中发布的链接@rmuller 编写了以下方法。如 Javadoc 和下图所示,此方法有大量文档,其中更具可读性。/**&nbsp;* Will find the method which the method <strong>methodElement</strong> is overriding, if any.&nbsp;* It does this by recursively traversing up the superclass tree of the&nbsp;* <strong>classElement</strong> and checking if there are methods which override the&nbsp;* <strong>methodElement</strong>. It will return after it finds the first method with the&nbsp;* annotation <strong>annotation</strong>.&nbsp;*&nbsp;* @param originalClassElement The original class inside which the&nbsp;*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<strong>methodElement</strong> is located.&nbsp;* @param classElement&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;The class which represents the superclass while recursively&nbsp;*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;looking up the tree, it should be equal to the&nbsp;*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<strong>originalClassElement</strong> when first calling this&nbsp;*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;method.&nbsp;* @param methodElement&nbsp; &nbsp; &nbsp; &nbsp; The method for which should be checked if it's overriding&nbsp;*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;anything.&nbsp;* @param annotation&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;The annotation which must be matched before returning the result&nbsp;* @return Will return the following, the list is written in order:&nbsp;*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<ul>&nbsp;*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<li>The method <strong>methodElement</strong> if <strong>methodElement</strong>&nbsp;*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;already has an annotation of the type <strong>annotation</strong></li>&nbsp;*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<li>Null if the method <strong>methodElement</strong> does not have an @Override&nbsp;*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;annotation</li>&nbsp;*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<li>Null if the class <strong>classElement</strong> does not have a superclass</li>&nbsp;*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<li>The method element which was found to have the annotation&nbsp;*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<strong>annotation</strong></li>&nbsp;*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</ul>&nbsp;*/public ExecutableElement getMethodOverride(TypeElement originalClassElement,&nbsp; &nbsp; &nbsp; &nbsp; TypeElement classElement, ExecutableElement methodElement,&nbsp; &nbsp; &nbsp; &nbsp; Class<? extends Annotation> annotation) {&nbsp; &nbsp; if (methodElement.getAnnotation(annotation) != null) {&nbsp; &nbsp; &nbsp; &nbsp; // The methodElement which was passed has the required annotation already&nbsp; &nbsp; &nbsp; &nbsp; return methodElement;&nbsp; &nbsp; }&nbsp; &nbsp; if (methodElement.getAnnotation(Override.class) == null) {&nbsp; &nbsp; &nbsp; &nbsp; // The methodElement which was passed does not have an @Override annotation and is&nbsp; &nbsp; &nbsp; &nbsp; // therefore not overriding anything.&nbsp; &nbsp; &nbsp; &nbsp; return null;&nbsp; &nbsp; }&nbsp; &nbsp; if (classElement.getSuperclass().getKind() == TypeKind.NONE) {&nbsp; &nbsp; &nbsp; &nbsp; // Class has no superclass&nbsp; &nbsp; &nbsp; &nbsp; return null;&nbsp; &nbsp; }&nbsp; &nbsp; for (Element elem : classElement.getEnclosedElements()) {&nbsp; &nbsp; &nbsp; &nbsp; if (elem.getKind() != ElementKind.METHOD) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Not a method&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; continue;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; // Check if the method inside the superclass overrids the method inside the original&nbsp; &nbsp; &nbsp; &nbsp; // class&nbsp; &nbsp; &nbsp; &nbsp; if (this.processingEnv.getElementUtils().overrides(methodElement,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (ExecutableElement) elem, classElement)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Recursively go up the tree and check since this method might also override&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // another method&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return getMethodOverride(originalClassElement,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.env.getElementUtils()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .getTypeElement(classElement.getSuperclass().toString()),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (ExecutableElement) elem, annotation);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; // Recursively go up the tree and check there&nbsp; &nbsp; return getMethodOverride(originalClassElement,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.env.getElementUtils().getTypeElement(classElement.getSuperclass().toString()),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; methodElement, annotation);}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java