使用JavaParser 如何获取一个Java类中的某个方法的返回类型呢?
假如有一个如下的简单的Java 类:
/**
* Copyright (C) Oscar Chen(XM):
*
* Date: 2024-11-21
* Author: XM
*/
package com.osxm.ai.sdlc.codeparse.codesample;
public class MyClass {
public String myMethod(String str) {
return str;
}
}
- 该类有一个返回String 类型的方法myMethod()
使用JavaParser 如何获取myMethod的返回类型,也就是String 呢?
获取方法的返回类型类的简化名
这里直接给实现代码:
// @formatter:off
String sourceCode = "public class MyClass {" +
"public String myMethod(String str){" +
"return str;" +
"}" +
"}";
// @formatter:on
@Test
public void methodReturnClassSimpleName() {
CompilationUnit cu = StaticJavaParser.parse(sourceCode);
String methodName = "myMethod";
MethodDeclaration methodDecl = cu.findAll(MethodDeclaration.class).stream()
.filter(md -> md.getName().getIdentifier().equals(methodName))
.findFirst()
.orElseThrow(() -> new RuntimeException("Method not found"));
Type returnType = methodDecl.getType();
String returnSimpleClassName = returnType.asString();
Assertions.assertEquals("String", returnSimpleClassName); // 获取方法返回类型的简化名
}
代码解释如下:
CompilationUnit cu = StaticJavaParser.parse(sourceCode);- 这行代码使用JavaParser库来解析给定的Java源代码字符串
sourceCode,并将其转换为一个CompilationUnit对象。CompilationUnit是JavaParser中表示整个Java源文件的一个抽象语法树(AST)的根节点。
- 这行代码使用JavaParser库来解析给定的Java源代码字符串
String methodName = "myMethod";- 这行代码定义了一个字符串变量
methodName,并将其值设置为"myMethod"。这是要查找的方法的名称。
- 这行代码定义了一个字符串变量
MethodDeclaration methodDecl = cu.findAll(MethodDeclaration.class).stream()- 这行代码开始通过
cu(即CompilationUnit对象)查找所有的方法声明(MethodDeclaration)。findAll(MethodDeclaration.class)返回一个包含所有方法声明的列表。 .stream()将这个列表转换为一个流(Stream),以便进行后续的流式处理。
- 这行代码开始通过
.filter(md -> md.getName().getIdentifier().equals(methodName))- 这行代码使用
filter方法过滤流中的元素。它保留那些其名称(通过md.getName().getIdentifier()获取)等于methodName(即"myMethod")的方法声明。
- 这行代码使用
.findFirst()- 这行代码尝试从过滤后的流中找到第一个元素(即第一个匹配的方法声明)。如果找到,它返回一个包含该元素的
Optional<MethodDeclaration>;如果没有找到,它返回一个空的Optional。
- 这行代码尝试从过滤后的流中找到第一个元素(即第一个匹配的方法声明)。如果找到,它返回一个包含该元素的
.orElseThrow(() -> new RuntimeException("Method not found"));- 这行代码处理上一步返回的
Optional。如果Optional是空的(即没有找到方法),则执行orElseThrow,抛出一个RuntimeException,异常信息为"Method not found"。如果Optional非空,即找到了方法,则将其值(MethodDeclaration对象)赋给methodDecl变量。
- 这行代码处理上一步返回的
Type returnType = methodDecl.getType();- 这行代码获取
methodDecl(即找到的myMethod方法)的返回类型,并将其存储在returnType变量中。
- 这行代码获取
String returnSimpleClassName = returnType.asString();- 这行代码将
returnType(即方法的返回类型)转换为其字符串表示形式,这里返回的是简化名。
- 这行代码将
Assertions.assertEquals("String", returnSimpleClassName);- 这行代码使用JUnit的
Assertions类来断言returnSimpleClassName(即方法的返回类型的字符串表示)是否等于字符串"String"。这是为了验证myMethod方法的返回类型确实是String。
- 这行代码使用JUnit的
现在问题来了, 如果要返回全限定名, 也就是这里的java.lang.String 要怎么处理呢?
获取方法的返回类型类的全限定名
同样,直接上代码:
@Test
public void methodReturnClassFullName() {
ReflectionTypeSolver reflectionTypeSolver = new ReflectionTypeSolver();
JavaSymbolSolver symbolSolver = new JavaSymbolSolver(reflectionTypeSolver);
// init parser
ParserConfiguration configuration = new ParserConfiguration().setSymbolResolver(symbolSolver);
// Setup parser
StaticJavaParser.setConfiguration(configuration);
CompilationUnit cu = StaticJavaParser.parse(sourceCode);
String methodName = "myMethod";
MethodDeclaration methodDecl = cu.findAll(MethodDeclaration.class).stream()
.filter(md -> md.getName().getIdentifier().equals(methodName))
.findFirst()
.orElseThrow(() -> new RuntimeException("Method not found"));
Type returnType = methodDecl.getType();
String returnSimpleClassName = returnType.asString();
Assertions.assertEquals("String", returnSimpleClassName); // 获取方法返回类型的简化名
String fullClassName = returnType.resolve().describe();
Assertions.assertEquals("java.lang.String", fullClassName); // 获取方法返回类型的全限定名
}
**重点: ** 要便捷的获取全限定名, 需要结合 JavaSymbolSolver ,也就是JavaParser-Symbol-Solver 这个库来使用。
完整的解释:
ReflectionTypeSolver是JavaSymbolSolver库中的一个组件,它使用Java反射API来解析类路径上的Java类文件,以获取类型信息。JavaSymbolSolver是一个更高级的组件,它使用TypeSolver(在这个例子中是ReflectionTypeSolver)来解决符号(如类型、方法等)的引用。- 这里创建了一个
ParserConfiguration对象,并通过setSymbolResolver方法设置了之前创建的JavaSymbolSolver实例。 - 然后,使用
StaticJavaParser.setConfiguration方法将这个配置应用到JavaParser上。这样,当JavaParser解析源代码时,它就可以使用JavaSymbolSolver来解决符号引用了。 returnType.resolve().describe()返回类型的完全描述,这通常包括类型的完全限定名以及任何泛型信息。对于基本类型或String等常见类型,这将返回它们的完全限定名。
完整代码如下:
/**
* Copyright (C) Oscar Chen(XM):
*
* Date: 2024-11-21
* Author: XM
*/
package com.osxm.ai.sdlc.javaparser;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import com.github.javaparser.ParserConfiguration;
import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.type.Type;
import com.github.javaparser.symbolsolver.JavaSymbolSolver;
import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
public class MethodInfo {
// @formatter:off
String sourceCode = "public class MyClass {" +
"public String myMethod(String str){" +
"return str;" +
"}" +
"}";
// @formatter:on
@Test
public void methodReturnClassSimpleName() {
CompilationUnit cu = StaticJavaParser.parse(sourceCode);
String methodName = "myMethod";
MethodDeclaration methodDecl = cu.findAll(MethodDeclaration.class).stream()
.filter(md -> md.getName().getIdentifier().equals(methodName))
.findFirst()
.orElseThrow(() -> new RuntimeException("Method not found"));
Type returnType = methodDecl.getType();
String returnSimpleClassName = returnType.asString();
Assertions.assertEquals("String", returnSimpleClassName); // 获取方法返回类型的简化名
}
@Test
public void methodReturnClassFullName() {
ReflectionTypeSolver reflectionTypeSolver = new ReflectionTypeSolver();
JavaSymbolSolver symbolSolver = new JavaSymbolSolver(reflectionTypeSolver);
// init parser
ParserConfiguration configuration = new ParserConfiguration().setSymbolResolver(symbolSolver);
// Setup parser
StaticJavaParser.setConfiguration(configuration);
CompilationUnit cu = StaticJavaParser.parse(sourceCode);
String methodName = "myMethod";
MethodDeclaration methodDecl = cu.findAll(MethodDeclaration.class).stream()
.filter(md -> md.getName().getIdentifier().equals(methodName))
.findFirst()
.orElseThrow(() -> new RuntimeException("Method not found"));
Type returnType = methodDecl.getType();
String returnSimpleClassName = returnType.asString();
Assertions.assertEquals("String", returnSimpleClassName); // 获取方法返回类型的简化名
String fullClassName = returnType.resolve().describe();
Assertions.assertEquals("java.lang.String", fullClassName); // 获取方法返回类型的全限定名
}
}







![Figure 02迎重大升级!!人形机器人独角兽[Figure AI]商业化加速](https://i-blog.csdnimg.cn/direct/2d10312665a44e82823379cec821a34d.png)












