有没有办法识别Java方法中使用的变量?

时间:2012-03-18 14:25:27

标签: java variables methods

有没有办法确定使用特定Java方法的变量?

例如,如果我有以下方法:

public void getResult(){
   int result = value1 + value2;
}

然后我需要一个包含名称result,value1和value2的列表。

2 个答案:

答案 0 :(得分:4)

只有在解析生成的字节代码时才能执行此操作。您可以使用字节码工程库,例如ASM,Javassist等。

据我所知,您的示例使用对象字段,这里的代码示例使用Javassist并打印给定类的方法使用的所有字段:

ClassFile cf = new ClassFile(new DataInputStream(className + ".class")));
for (Object m : cf.getMethods()) {
    MethodInfo minfo = (MethodInfo)m;
    CodeAttribute ca = minfo.getCodeAttribute();
    for (CodeIterator ci = ca.iterator(); ci.hasNext();) {
        int index = ci.next();
        int op = ci.byteAt(index);
        if (op == Opcode.GETYFIELD) {
                    int a1 = ci.s16bitAt(index + 1);
                    String fieldName = " " + cf.getConstPool().getFieldrefName(a1); 
            System.out.println("field name: " + fieldName);
        }
    }

}

答案 1 :(得分:4)

这取决于您在编译时是否启用了调试信息。如果没有,它会丢弃变量名称,它们只是由它们的堆栈地址引用引用。通常,您为编译器提供“-g”选项来执行此操作,但是如果您使用的是maven,请查看它的文档以了解如何确保它已启用。

如果启用了调试,您可以使用像BCEL这样的库来查找此信息:

java.lang.reflect.Method javaMethod = ...; // lookup the actual method using reflection
org.apache.bcel.classfile.JavaClassjc = org.apache.bcel.Repository.lookupClass(classname);
org.apache.bcel.classfile.Method method = jc.getMethod(javaMethod);
org.apache.bcel.classfile.LocalVariableTable lvt = method.getLocalVariableTable();

从那里,LocalVariableTable有很多方法可以获取局部变量列表(参见bcel文档)。

有几个软件包可以做到这一点,但BCEL和Javassist让我想到了。