如何从JAVA文件解析静态级别变量?

时间:2019-01-17 09:29:01

标签: java spring parsing javaparser javasymbolsolver

我正在尝试从JAVA文件中解析静态变量值。但是无法解析变量。

我已经使用JavaParser解析代码并获取变量的值。我在获取所有其他类级别的变量和值方面都取得了成功,但无法解析静态字段。

Java文件看起来像...

public class ABC {
    public string variable1 = "Hello How are you?";
    public boolean variable2 = false;
    public static String variable3;
    static{
    variable3 = new String("Want to Fetch this...");
    } 
    //Can't change this file, this is input.
    public static void main(String args[]){
    //....Other Code
    } 
}

我能够解析除“ variabl3”之外的所有变量值。 Java文件的代码类似于上面的Java代码,我需要解析“ variable3”的值。

我已经完成了下面的代码来解析类级变量...

import java.util.HashMap;
import java.util.List;

import com.github.javaparser.ast.body.FieldDeclaration;
import com.github.javaparser.ast.body.VariableDeclarator;
import com.github.javaparser.ast.expr.VariableDeclarationExpr;
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;


public class StaticCollector extends 
VoidVisitorAdapter<HashMap<String, String>> {

@Override
public void visit(FieldDeclaration n, HashMap<String, String> arg) {
    // TODO Auto-generated method stub
    List <VariableDeclarator> myVars = n.getVariables();
        for (VariableDeclarator vars: myVars){
            vars.getInitializer().ifPresent(initValue -> System.out.println(initValue.toString()));
            //System.out.println("Variable Name: "+vars.getNameAsString());
            }
}

}

主要方法...

public class Test {
public static void main(String[] args) {

    File file = new File("filePath");
    CompilationUnit compilationUnit = null;
    try {
        compilationUnit = JavaParser.parse(file);
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    HashMap<String, String> collector = new HashMap<String, String>();
    compilationUnit.accept(new StaticCollector(), collector);
} 
}

如何解析“ variable3”的值,该值是静态的并且在静态块内分配了值?代码中可能还有其他变量,但是我需要找到特定变量值的值(在这种情况下为Variable3)。 我是在做错事还是需要添加其他方式,请提出建议。

1 个答案:

答案 0 :(得分:0)

Inspecting the AST as something that's easily readable, e.g., a DOT (GraphViz) image with PlantUML是解决此类问题的巨大帮助。参见this blog on how to generate the DOT as well as other formats

这里是概述,突出显示了“ variable3”节点(我只是在.dot输出中进行搜索并添加了填充颜色)。您会看到它发生了两个点:

enter image description here

放大右侧的节点空间,可以看到第二个子树在InitializerDeclaration下。再往下,它是AssignExpr的一部分,其中值是ObjectCreationExpr

enter image description here

因此,我适应了Visitor(这是一个使模块自包含的内部类),您需要重写visit(InitializerDeclaration n...方法才能到达所需位置:

import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.body.FieldDeclaration;
import com.github.javaparser.ast.body.InitializerDeclaration;
import com.github.javaparser.ast.body.VariableDeclarator;
import com.github.javaparser.ast.stmt.Statement;
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.List;

public class Test {
    public static void main(String[] args) {

        File file = new File("src/main/java/ABC.java");
        CompilationUnit compilationUnit = null;
        try {
            compilationUnit = StaticJavaParser.parse(file);
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        HashMap<String, String> collector = new HashMap<String, String>();
        compilationUnit.accept(new StaticCollector(), collector);
    }

    private static class StaticCollector extends
            VoidVisitorAdapter<HashMap<String, String>> {
        @Override
        public void visit(FieldDeclaration n, HashMap<String, String> arg) {
            List<VariableDeclarator> myVars = n.getVariables();
            for (VariableDeclarator vars: myVars){
                vars.getInitializer().ifPresent(initValue -> System.out.println(initValue.toString()));
                //System.out.println("Variable Name: "+vars.getNameAsString());
            }
        }
        @Override
        public void visit(InitializerDeclaration n, HashMap<String, String> arg) {
            List<Statement> myStatements = n.getBody().getStatements();
            for (Statement s: myStatements) {
                s.ifExpressionStmt(expressionStmt -> expressionStmt.getExpression()
                        .ifAssignExpr(assignExpr -> System.out.println(assignExpr.getValue())));
            }
        }
    }
}

以下是在静态块中另外显示variable3的初始化的输出:

"Hello How are you?"
false
new String("Want to Fetch this...")