首页 > 解决方案 > 如何列出该类中可变的Java类中的所有变量

问题描述

我有一个大约 200 个 Java 类的列表。我需要准备一个变量列表(特别是静态的和非最终的),其值在 Java 类中被修改/变异。为了准备所有静态和非最终变量的列表,我使用了反射。

但是我不确定如何检查类中的每个变量是否都发生了突变,而无需手动打开每个文件。

class ClassVO{
    private static final String name;
    private String fieldName;
    private static double single=0.01;
    private static double value;

   void calculate(){
     value = value*0.25;
   }
}

在上面的示例中,需要返回“值”变量。是否有任何可用的工具可用于完成此类工作?请分享。

标签: javastatic

解决方案


这样做的方法很困难,我使用了可以加载 JavaClass 文件的 Apache bcel 库。
bcel-6.0.jar 示例输入类:-

public class Test {
    private static final String name = "";
    private String fieldName;
    private static String  single = "notMutable";
    private static double value;
    private String random;

    public void print(){
        value = value*0.25;
        fieldName = "foo";
        String sample =single+"1";
    }
}

检查方法中变量(静态/实例)引用的代码

import java.util.ArrayList;
import java.util.List;
import org.apache.bcel.Repository;
import org.apache.bcel.classfile.JavaClass;
import org.apache.bcel.classfile.Method;

public class Sample {
    public static void main(String[] args) {
        try {
            List<String> usedVariables = new ArrayList<String>();
            JavaClass  javaClass =  Repository.lookupClass(Test.class);
            for(Method m: javaClass.getMethods()) {
                String code = m.getCode().toString();
                String[] codes = code.split("\\r?\\n");
                if(!m.getName().matches("<clinit>|<init>")) {
                    for(String c: codes) {
                        if(c.contains(javaClass.getClassName()+".") && (c.contains("putstatic") || c.contains("putfield"))) {
                            System.out.println("Class static/Instant mutable variable Used inside method @ --> "+c);
                            String variableName = c.substring(c.indexOf(javaClass.getClassName()));
                            usedVariables.add(variableName.split(":")[0]);
                        }
                    }
                }
            }
            System.out.println("Result --> " +usedVariables);
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

输出

Class static/Instant mutable variable Used inside method @ --> 7:    putstatic      Test.value:D (30)
Class static/Instant mutable variable Used inside method @ --> 13:   putfield       Test.fieldName:Ljava/lang/String; (36)
Result --> [Test.value, Test.fieldName]

尽管在方法内部使用了print静态变量值和单变量值,但变量single值在更改时没有更改,value因此
输出仅显示可变字段,即。

Result --> [Test.value, Test.fieldName]

推荐阅读