在编译时获取要在处理器内部进行方法调用 (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类进行比较并对其进行验证?

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

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

这将导致以下代码:

// 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.
...

最新更新