2012-12-18 65 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