2012-03-18 183 views

回答

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); 
     } 
    } 

}

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让我想起了我的头顶。

相关问题