如何使用JavaSymbol Solver获取注解的限定类名?
解决JavaSymbol Solver获取注解限定类名时的ClassCastException问题
这个ClassCastException的问题很常见——你直接调用javaParserFacade.solve(annotation)的方式不对。因为Java里的注解本质是特殊的接口,所以solve()返回的是接口类型的声明(也就是JavassistInterfaceDeclaration),而不是你期望的ResolvedAnnotationDeclaration,类型不匹配自然就抛出异常了。
修正后的代码
下面是能正确获取注解限定类名的代码:
final CombinedTypeSolver combinedTypeSolver = new CombinedTypeSolver(); combinedTypeSolver.add(new ReflectionTypeSolver()); combinedTypeSolver.add(new JarTypeSolver(JUNIT_PATH)); final JavaParserFacade javaParserFacade = JavaParserFacade.get(combinedTypeSolver); final CompilationUnit cu = JavaParser.parse("package apackage;\n" + "\n" + "import org.junit.*;\n" + "\n" + "public class ClassToAnalyze {\n" + "\n" + "@Test\n" + " public void test() {\n" + " \n" + " }\n" + "}\n" + ""); final TypeDeclaration<?> typeDeclaration = cu.getTypes().get(0); final MethodDeclaration method = typeDeclaration.getMethods().get(0); final AnnotationExpr annotation = method.getAnnotation(0); // 第一步:解析注解名称对应的类型 ResolvedType annotationType = javaParserFacade.getType(annotation.getName()); // 第二步:将类型转为引用类型,再获取注解声明 ResolvedAnnotationDeclaration annotationDeclaration = annotationType.asReferenceType().getTypeDeclaration().asAnnotation(); // 输出@Test的限定类名:org.junit.Test System.out.println(annotationDeclaration.getQualifiedName());
关键说明
- 注解的本质:Java注解在编译后会被处理成继承自
java.lang.annotation.Annotation的接口,所以直接解析AnnotationExpr会得到接口声明,而非注解专属的声明类型。 - 正确流程:先通过注解的名称表达式(
annotation.getName())解析其类型,再将该类型转换为引用类型,最后通过asAnnotation()将接口声明转为注解声明,这样就能安全获取到限定类名了。
另外,你使用的javaparser 3.6.5和javasymbol solver 0.6.3版本是匹配的(symbolsolver 0.6系列对应javaparser 3.6系列),版本本身没有问题,只是调用逻辑需要调整。
内容的提问来源于stack exchange,提问作者Luis M. Villa
相关产品推荐
相关产品推荐

