2012-03-18 102 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讓我想起了我的頭頂。

相關問題