为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

SMILET 2021-12-22 20:14:09
代码结构假设我们有一个这样的结构:class A {    @AMethodAnnotation("my-data")    public void myMethod() {    }}@MyClassAnnotationclass 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,然后您必须验证方法名称是否相同,以及参数是否相同且顺序相同。但是我发现这种方法需要大量检查,因此我的问题是是否有更好的方法。
查看完整描述

1 回答

?
慕妹3242003

TA贡献1824条经验 获得超6个赞

我根据评论中发布的链接@rmuller 编写了以下方法。如 Javadoc 和下图所示,此方法有大量文档,其中更具可读性。

//img1.sycdn.imooc.com//61c316af0001655e06510337.jpg

/**

 * Will find the method which the method <strong>methodElement</strong> is overriding, if any.

 * It does this by recursively traversing up the superclass tree of the

 * <strong>classElement</strong> and checking if there are methods which override the

 * <strong>methodElement</strong>. It will return after it finds the first method with the

 * annotation <strong>annotation</strong>.

 *

 * @param originalClassElement The original class inside which the

 *                             <strong>methodElement</strong> is located.

 * @param classElement         The class which represents the superclass while recursively

 *                             looking up the tree, it should be equal to the

 *                             <strong>originalClassElement</strong> when first calling this

 *                             method.

 * @param methodElement        The method for which should be checked if it's overriding

 *                             anything.

 * @param annotation           The annotation which must be matched before returning the result

 * @return Will return the following, the list is written in order:

 *         <ul>

 *         <li>The method <strong>methodElement</strong> if <strong>methodElement</strong>

 *         already has an annotation of the type <strong>annotation</strong></li>

 *         <li>Null if the method <strong>methodElement</strong> does not have an @Override

 *         annotation</li>

 *         <li>Null if the class <strong>classElement</strong> does not have a superclass</li>

 *         <li>The method element which was found to have the annotation

 *         <strong>annotation</strong></li>

 *         </ul>

 */

public ExecutableElement getMethodOverride(TypeElement originalClassElement,

        TypeElement classElement, ExecutableElement methodElement,

        Class<? extends Annotation> annotation) {


    if (methodElement.getAnnotation(annotation) != null) {

        // The methodElement which was passed has the required annotation already

        return methodElement;

    }


    if (methodElement.getAnnotation(Override.class) == null) {

        // The methodElement which was passed does not have an @Override annotation and is

        // therefore not overriding anything.

        return null;

    }


    if (classElement.getSuperclass().getKind() == TypeKind.NONE) {

        // Class has no superclass

        return null;

    }


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

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

            // Not a method

            continue;

        }


        // Check if the method inside the superclass overrids the method inside the original

        // class

        if (this.processingEnv.getElementUtils().overrides(methodElement,

                (ExecutableElement) elem, classElement)) {


            // Recursively go up the tree and check since this method might also override

            // another method

            return getMethodOverride(originalClassElement,

                    this.env.getElementUtils()

                            .getTypeElement(classElement.getSuperclass().toString()),

                    (ExecutableElement) elem, annotation);

        }


    }


    // Recursively go up the tree and check there

    return getMethodOverride(originalClassElement,

            this.env.getElementUtils().getTypeElement(classElement.getSuperclass().toString()),

            methodElement, annotation);

}


查看完整回答
反对 回复 2021-12-22
  • 1 回答
  • 0 关注
  • 158 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号