如何在注解处理环境中查找匿名类?

问题描述 投票:0回答:0

我正在用 Java 8 编写注释处理器。

假设我在项目的某处有这样的课程:

public class SampleClass {
    public void foo(int i) {
        new Runnable() {
            @Override
            public void run() {
                System.out.println(i);
            }
        };
    }
}

在我的代码中的某处else,我有我的注释,包含 SampleClass 的完全限定名称和编译后标识匿名类的唯一整数(如 SampleClass$id 中)。

要执行我的任务,我需要找到代表该特定匿名类的

javax.lang.model.element.Element
对象。或者,除此之外,至少获取代表某个类中的匿名类的
Element
对象的列表将是一个开始。我很确定这是可能的,因为在
javax.lang.model
包的文档中多次引用了匿名类,但我不知道在我的案例中你会如何具体地得到它们。

我确实尝试了最明显的事情。假设我想编写一个方法,给定一个类的完全限定名称 (

fqn
) 和一个
ProcessingEnvironment
对象 (
env
),构建该元素中包含的所有匿名类的列表(并且,递归地,它的每个子元素,以及它们的子元素,等等)。这是我最好的猜测:

public List<Element> findAnonymousClasses(String fqn, ProcessingEnvironment env) {
    Element sampleClassElement = processingEnvironment.getElementUtils().getTypeElement(fqn);
    List<Element> anons = new ArrayList<>();
    sampleClassElement.getEnclosedElements()
        .forEach(e -> {
            if(e.getSimpleName().length() == 0)
                anons.add(e);
            anons.addAll(getAnonymousClasses(e, env));
    });
}

我的推理是

getSimpleName()
,根据其文档:

如果它表示一个匿名类或实例初始化器,则返回一个空名称。

空的 {@code Name} 的长度为零。

代码显然有缺陷,因为它也会在类的方法中返回匿名类,但它至少应该返回一些东西!然而,显然,

List
是空的。将
e.getSimpleName().length() == 0
替换为
e instanceof TypeElement && ((TypeElement) e).getNestingKind() == NestingKind.ANONYMOUS
会产生相同的结果。

进一步检查发现问题不在于我如何过滤它。相反,

Element.getEnclosedElements()
似乎从不包含匿名类。那我怎么才能找到他们呢?当然,如果在(即
NestingKind.ANONYMOUS
)中编码了对它们的处理,那么它们必须以某种方式获得吗?希望这里的任何人都能给我一个正确的方向。

java abstract-syntax-tree annotation-processing anonymous-class
© www.soinside.com 2019 - 2024. All rights reserved.