使用 JavaParser 解析提取Java文件中的class/method/interface名称


=Start=

缘由:

前段时间事情太多,没时间去维护博客,间断了快一个月,最近稍微好了一些,重新开始整理记录,记录分享的好习惯还是要保持,否则时间也很可能被浪费去刷手机了……

这里简单整理记录一下如何提取Java文件中的类名、方法名、接口名等信息的方法。最容易想到的有一种方法是借助正则表达式进行提取,不过这对Java文件的内容格式有一定要求,且准确率会有天然的天花板在那(非语义程度,仅当成字符串处理,误报不可避免);另一种方式就是利用一些AST的解析器来实现,这里要介绍的也是这种,方便以后需要的时候使用。

正文:

参考解答:

大致思路或方法其实就是继承某个Visitor(比如这里的:VoidVisitorAdapter)覆写其中的visit方法,添加打印或是其它的一些自定义功能。

import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.body.TypeDeclaration;
import com.github.javaparser.ast.visitor.VoidVisitor;
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
import com.google.common.base.Strings;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import static com.github.javaparser.StaticJavaParser.parse;


public class JavaParserListFileClassNames {
    public void listClasses(File projectDir) {
        new DirExplorer((level, path, file) -> path.endsWith(".java"), (level, path, file) -> {
            System.out.println(path);
            System.out.println(Strings.repeat("=", path.length()));
            try {
                new VoidVisitorAdapter<Object>() {
                    @Override
                    public void visit(ClassOrInterfaceDeclaration n, Object arg) {
                        super.visit(n, arg);
                        System.out.println(" * " + n.getName());
                    }

                    @Override
                    public void visit(MethodDeclaration n, Object arg) {
                        super.visit(n, arg);
                        System.out.println("   -> " + n.getName());
                    }
                }.visit(parse(file), null);
                System.out.println(); // empty line
            } catch (IOException e) {
                new RuntimeException(e);
            }
        }).explore(projectDir);
    }

    private static String parseClassname(File filename) throws Exception {
        try (FileInputStream fin = new FileInputStream(filename)) {
            CompilationUnit cu = parse(fin);

            VoidVisitor<?> methodNameVisitor = new MethodNamePrinter();
            methodNameVisitor.visit(cu, null);

            for (TypeDeclaration type : cu.getTypes()) {
                // System.out.println(type.getFullyQualifiedName().toString());
                if (type instanceof ClassOrInterfaceDeclaration)
                    return type.getNameAsString();
            }
            // for (Node node: cu.getChildNodes()) {
            //     System.out.println(node);
            //     System.out.println(node.getAllContainedComments());
            // }
        }
        return null;
    }

    public static void main(String[] args) {
        File projectDir = new File("/path/to/FileName.java");
        JavaParserListFileClassNames javaParserListFileClassNames = new JavaParserListFileClassNames();
        try {
            System.out.println(javaParserListFileClassNames.parseClassname(projectDir));
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println();

        projectDir = new File("/path/to/dir");
        javaParserListFileClassNames.listClasses(projectDir);
    }

    private static class MethodNamePrinter extends VoidVisitorAdapter<Void> {
        @Override
        public void visit(MethodDeclaration md, Void arg) {
            super.visit(md, arg);
            System.out.println("Method Name Printed: " + md.getName());
        }
    }
}
参考链接:

https://stackoverflow.com/questions/23017557/how-to-get-class-name-of-any-java-file/40488118#40488118

https://github.com/javaparser/javaparser

http://javaparser.org/getting-started.html

https://leanpub.com/javaparservisited

Getting started with JavaParser: analyzing Java Code programmatically(时间太久,版本太老,接口已更新,原有代码不可直接用,不过思路可以参考(简单改改内容也基本可用))
https://tomassetti.me/getting-started-with-javaparser-analyzing-java-code-programmatically/

Some examples of code extracting information from Java source files using JavaParser
https://github.com/ftomassetti/analyze-java-code-examples
https://github.com/javaparser/javaparser/issues/2181

=END=


《“使用 JavaParser 解析提取Java文件中的class/method/interface名称”》 有 1 条评论

  1. JavaParse(AST)获取Java Web API list
    https://mp.weixin.qq.com/s/ATpoEN9QI-D5vkxDimQ8FQ
    `
    0x01 目标
    目标:将代码中的WebAPI解析出来

    0x02 效果
    解析完成后的效果大致是这样的,然后在针对要筛选的条件,对api进行筛选即可,例如 RequestMapping等

    0x03 代码实现
    Gist: https://gist.github.com/B1ueB0ne/7ee600305364f76bf5105c98054f62e6

    0x04 parse方法详解
    com.github.javaparser.JavaParser#parse
    com.github.javaparser.JavaParser#simplifiedParse
    com.github.javaparser.JavaParser#CompilationUnit
    `

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注