java - 如何在读取java源文件时查找变量的类型

标签 java parsing

假设我有一个 java 源文件 (source.java),如下所示。

1  package demo;
2
3  public class Source {
4
5   public static void main(String[] args) {
6
7       String sample = "foo bar";
8       
9       System.out.println(sample.length());
10
11     }
12  }

现在我想编写一个 java 代码逐行读取这个源文件,当它在第 9 行遇到 sample 变量时,它会告诉我哪个类(即 java. lang.String) 示例变量所属。我怎样才能做到这一点? 我已经看到下面的链接,它对我不起作用,因为它在同一个源文件中打印类型名称。

Print the type of a Java variable

最佳答案

要阅读一个独立的java源文件,您必须从头开始,逐行阅读,按照Java的语法解析文件的每个单词,...要做的工作太多了。或者我推荐JavaParser .

JavaParser读取原始 Java 源文件并将其解析为可以检索信息的 Java 对象。

这是您的问题的示例代码:

public String getSampleVariableType() throws Exception {
    // Use the raw text of file as input
    // `CompilationUnit` contains all information of your Java file.
    CompilationUnit compilationUnit = JavaParser.parse("package demo;\n" +
            "\n" +
            "public class Source {\n" +
            "    public static void main(String[] args) {\n" +
            "        String sample = \"foo bar\"; \n" +
            "        System.out.println(sample.length());\n" +
            "    }\n" +
            "}");

    // Find class by name
    ClassOrInterfaceDeclaration clazz = compilationUnit.getClassByName("Source")
                                                       .orElse(null);
    if (clazz == null) 
        throw new ClassNotFoundException();

    // Find method by name
    List<MethodDeclaration> methods = clazz.getMethodsByName("main");
    if (methods.size() == 0) 
        throw new MethodNotFoundException();

    // Get the content of method's body
    MethodDeclaration method = methods.get(0);
    BlockStmt block = method.getBody().orElse(null);
    if (block == null) 
        throw new MethodEmptyException();

    // Statement `String sample = "foo bar";` is a VariableDeclaration.
    // Find all VariableDeclaration in current method, filter as you want
    // and get its class type by using `getType()` method
    return block.findAll(VariableDeclarator.class).stream()
            .filter(v -> v.getName().asString().equals("sample"))
            .map(v -> v.getType().asString())
            .findFirst().orElse(null);
}

结果是类型的简单名称:String

为了将结果表示为完全限定名称(即 java.lang.String)。您可能需要找到所有 ImportDeclaration 并找到导入的名称:

public static String getFullyQualifiedName(CompilationUnit cu, String simpleName) {
    return cu.findAll(ImportDeclaration.class).stream()
         .filter(i -> i.getName().asString().matches(".*\\b" + simpleName + "\\b"))
         .map(i -> i.getName().asString())
         .findFirst().orElse("java.lang." + simpleName);
}

关于java - 如何在读取java源文件时查找变量的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51117783/

相关文章:

java - 确定java中InputStream中下一个读取的类型

java - iText 字体设置为短语未反射(reflect)

c++ - 将 Hex Char 转换为 Int - 有更好的方法吗?

java - Maven jar 插件 - 无法读取 Artifact 描述符

java - App Engine : How does memory work?(将 Mahout 与 App Engine 结合使用)

scala - 如何实现单子(monad)解析?

ios - 将 NSString 转换为整数

c - 解析 C 中的整数和字符数组

Java - Decimal Format.parse 以返回具有指定小数位数的 double 值

java - MouseDragged 和 MouseMoved 在 Java Applet 中不起作用