首页 > 解决方案 > 在编译时获取处理器内部方法调用(ExecutableElement)的参数类

问题描述

我有一个类,在其中我有一个带有自定义注释的方法,该方法在编译时使用处理器进行处理。

@Controller
public class ExampleController {

    @ListenFor
    public void handleRequest(Object something, String other) {

    }
}

我想验证该方法所期望的第二个参数的类并确保它是String.

在处理器内部,我获取方法的可执行元素并从中获取参数作为变量元素:

ExecutableElement exeElement = (ExecutableElement) e;

List<? extends VariableElement> params = exeElement.getParameters();

如何在处理器内部的编译时获取第二个参数(String other)的类,以便我可以将它与String类进行比较并验证它?

标签: java

解决方案


由于您在编译时进行操作,因此您不一定要依赖Class实例。相反,编译时类型有另一种表示形式,称为TypeMirror.

我们可以TypeMirror通过Element。由于上述原因,无法从 aElement#asType()获取Class对象。TypeMirror为了检查第二个参数是否为 a String,我们需要转换String.class为 a TypeMirror。方法Elements#getTypeElement(CharSequence name)给了我们一个TypeMirror, 给定一个规范的名字。Class我们可以通过 获取实例的规范名称Class#getCanonicalName()

这导致以下代码:

// assuming the processingEnvironment got passed to the method.
// It is a good idea to store the elementUtil somewhere
// globally accessible during annotation processing.
Elements elementUtils = processingEnvironment.getElementUtils();
...
TypeMirror stringType =
    elementUtils.getTypeElement(String.class.getCanonicalName()).asType();
...
ExecutableElement exeElement = (ExecutableElement) e;
List<? extends VariableElement> params = exeElement.getParameters();
TypeMirror secondArgumentType = params.get(1).asType();

// I find the explicit version has a less cognitive complexity. Feel free to change it.
if (secondArgumentType.equals(stringType) == false) { 
    // TODO: halt and catch fire!
}

// from here on, you can be certain that the second argument is a String.
...

推荐阅读