我有一个大约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;
}
}
在上面的例子中,"value "变量需要被返回。有什么工具可以用来实现这种工作吗?请分享一下。
有一个困难的方法来做到这一点,我已经使用Apache bcel库,它可以加载JavaClass文件。即。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";
}
}
检查方法中变量引用(staticinstance)的代码。
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]