Java注解处理器如何获取被注解类方法返回类型的字段与方法
解决方案
问题根本原因
你遇到的两个问题本质是注解处理器的运行机制导致的:
- 注解处理运行在Java编译的前期阶段,此时app模块的类还未完成编译生成字节码,处理器的类加载器无法加载未编译完成的类,因此
Class.forName必然抛出ClassNotFoundException。 - app模块已经依赖了processor模块,若processor再反向依赖app就会出现循环依赖,不符合项目依赖的单向原则。
正确实现方式
不需要依赖反射,直接使用注解处理器提供的Element、TypeMirror系列API即可在编译期获取返回类型的所有字段、方法信息,完全不需要引入app模块的依赖。
步骤1:补充初始化Types工具类
修改你的MyAnnotationProcessor的init方法,添加Types工具类的初始化,它用来处理类型相关的操作:
private Types typeUtils; // 新增成员变量 @Override public synchronized void init(ProcessingEnvironment processingEnv) { super.init(processingEnv); filer = processingEnv.getFiler(); messager = processingEnv.getMessager(); elementUtils = processingEnv.getElementUtils(); typeUtils = processingEnv.getTypeUtils(); // 新增赋值 }
步骤2:解析返回类型的类信息
拿到方法的returnType后,将其转为TypeElement即可遍历该类的所有成员:
TypeMirror returnType = ((ExecutableElement)method).getReturnType(); // 先判断返回类型是普通类类型 if (returnType.getKind() != TypeKind.DECLARED) { messager.printMessage(Kind.ERROR, "返回类型不是可解析的类类型", method); return false; } // 转为声明类型后拿到对应的TypeElement DeclaredType declaredReturnType = (DeclaredType) returnType; TypeElement returnClassElem = (TypeElement) declaredReturnType.asElement(); // 遍历返回类的所有成员,获取字段、方法信息 for (Element member : returnClassElem.getEnclosedElements()) { // 处理字段 if (member.getKind() == ElementKind.FIELD) { VariableElement field = (VariableElement) member; String fieldName = field.getSimpleName().toString(); String fieldType = field.asType().toString(); messager.printMessage(Kind.WARNING, "返回类字段:" + fieldName + ",类型:" + fieldType); } // 处理方法 else if (member.getKind() == ElementKind.METHOD) { ExecutableElement methodElem = (ExecutableElement) member; String methodName = methodElem.getSimpleName().toString(); int paramCount = methodElem.getParameters().size(); messager.printMessage(Kind.WARNING, "返回类方法:" + methodName + ",参数数量:" + paramCount); } }
补充说明
通过这种方式你可以拿到返回类的所有编译期可见信息,包括注解、修饰符、泛型参数、父类/实现接口等,完全可以满足代码生成的需求,不需要依赖任何app模块的代码,也不会出现循环依赖问题。
内容的提问来源于stack exchange,提问作者firegloves
相关产品推荐
相关产品推荐

