我需要从某些Java类中解析某些方法调用调用,包括整个签名。

public class MyClass {
    public void myMthod() {
        // ... some code here
        result = someInstance.someOtherMethod(param1, param2);
        // ... some other code here
    }
}

结果,我想得到类似的东西:
serviceName = someInstance
methodName = someOtherMethod
arguments = {
   argument = java.lang.String,
   argument = boolean
}
result = java.lang.Long

最快的方法是什么?
我在考虑使用RegEx解析器。存在的问题有几种发生方式,例如
a)
result = someInstance.someOtherMethod(getSomething(), param);

b)
result =
    getSomeInstance().someOtherMethod(param);

c)
result = getSomeInstance()
            .someOtherMethod(
                    getSomethingElse(), null, param);

任何帮助将非常感激!谢谢!

最佳答案

不要使用正则表达式!使用了解Java的工具。

使用以下任一方法:

  • 源代码解析器(例如javaparser)
  • 字节码分析(例如ASM)
  • 方面(AspectJ)

  • 在源解析器和ASM中,您都将编写一个访问者,以扫描方法调用。

    对于javaparser:阅读this page,扩展VoidVisitorAdapter并覆盖
    public void visit(MethodCallExpr n, A arg)
    

    样例代码:
    public static void main(final String[] args) throws Exception{
        parseCompilationUnit(new File("src/main/java/foo/bar/Phleem.java"));
    }
    
    public static void parseCompilationUnit(final File sourceFile)
        throws ParseException, IOException{
        final CompilationUnit cu = JavaParser.parse(sourceFile);
        cu.accept(new VoidVisitorAdapter<Void>(){
    
            @Override
            public void visit(final MethodCallExpr n, final Void arg){
                System.out.println(n);
                super.visit(n, arg);
            }
        }, null);
    }
    

    这里的问题是您只有对象名称,而没有对象类型,因此还必须保留一个变量/字段的本地Map进行输入,这会使事情变得混乱。毕竟,也许ASM是更容易的选择。

    对于ASM:阅读this tutorial page以开始使用

    10-07 16:31
    查看更多