2012-12-18 68 views
2

是否可以讀取或識別來自java字節碼的INVOKESPECIAL指令正在引用哪個類?如果是,如何?另外,如何知道在跳轉後執行的下一行是什麼?瞭解字節碼java

請記住,我想製作一個程序來做到這一點。我想要做的是找到一種方法來自動地通過字節碼本地化異常處理。

+0

異常處理位於異常表中,該異常表列出了從正常執行到重新執行塊的重定向。 – assylias

+0

你是指什麼課程?你的意思是該方法首次定義的類/接口,還是實際被調用的方法? – Dunes

+0

好吧,如果有I/O異常,I/O異常類將被調用,對吧?我想知道這是被調用的這個類 – user1912475

回答

1

你可以檢查這個框架約http://asm.ow2.org/。 「ASM框架是用於字節碼操作的最快,最靈活和衆所周知的框架」

+0

ASM框架向我顯示字節碼,但我的程序究竟能夠讀取框架所說的內容? – user1912475

0

有很多框架將它們用於字節碼操作there。但我個人更喜歡ASM。它的XML解析機制更容易學習。

例如,您可以使用此代碼列出所有INVOKESPECIAL呼召在一個jar文件: 它將打印線是這樣的:

INVOKESPECIAL[ opcode=183, owner=java/lang/StringBuilder, name=<init>, desc=()V]

你可以說它是INVOKESPECIAL所引用的java/lang/StringBuilder<init>功能。

JarFile jarFile = new JarFile("xxx.jar"); 
Enumeration<JarEntry> entries = jarFile.entries(); 

while (entries.hasMoreElements()) { 
    JarEntry jarEntry = entries.nextElement(); 
    if (jarEntry != null && jarEntry.getName().endsWith(".class")) { 
     InputStream eis = jarFile.getInputStream(jarEntry); 
     ClassReader classReader = new ClassReader(eis); 
     ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); 
     MyClassVisitor mcw = new MyClassVisitor(Opcodes.ASM4, cw); 
     classReader.accept(mcw, 0); 
     eis.close(); 
    } 
} 


class MyClassVisitor extends ClassVisitor { 
private int api; 
public MyClassVisitor(int api, ClassWriter cw) { 
    super(api, cw); 
    this.api = api; 
} 
@Override 
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { 
    MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); 
    return new MyMethodVisitor(api, mv); 
} 
class MyMethodVisitor extends MethodVisitor { 

    public MyMethodVisitor(int api, MethodVisitor mv) { 
     super(api, mv); 
    } 
    @Override 
    public void visitMethodInsn(int opcode, String owner, String name, String desc) { 
     if (opcode == Opcodes.INVOKESPECIAL) { 
      System.out.println("INVOKESPECIAL[ opcode=" + opcode + ", owner=" + owner + ", name=" + name 
        + ", desc=" + desc+"]"); 
     } 
     super.visitMethodInsn(opcode, owner, name, desc); 
    } 
} 
} 
+0

我該如何接收代碼塊而不是jar文件? – user1912475

+0

您需要將該代碼塊編譯爲'.class'文件。然後你可以把它給「ClassReader」! – Akdeniz

+0

好吧,但是如果我按字節碼指令接收字節碼指令,我可以只將這些指令一次一個地發送給ClassReader,它會起作用嗎? – user1912475