java如何返回之前代码_java – 如何在每次返回之前向消息添加代码?

你有两个解决方案:

1.在MethodVisitor中使用visitInsn(int opcode)方法:

//this is the custom method visitor

private class InsertInitCodeBeforeReturnMethodVisitor extends MethodVisitor{

public InsertInitCodeBeforeReturnMethodVisitor(MethodVisitor mv) {

super(Opcodes.ASM4, mv);

}

@Override

public void visitInsn(int opcode) {

//whenever we find a RETURN, we instert the code, here only crazy example code

switch(opcode) {

case Opcodes.IRETURN:

case Opcodes.FRETURN:

case Opcodes.ARETURN:

case Opcodes.LRETURN:

case Opcodes.DRETURN:

case Opcodes.RETURN:

mv.visitVarInsn(Opcodes.ALOAD, 42);

break;

default: // do nothing

}

super.visitInsn(opcode);

}

}

//this is the custom method visitor

private class InsertInitCodeBeforeReturnMethodVisitor extends AdviceAdapter{

public InsertInitCodeBeforeReturnMethodVisitor(MethodVisitor mv, int access, String name, String desc) {

super(Opcodes.ASM4, mv, access, name, desc);

}

@Override

protected void onMethodExit(int opcode) {

if(opcode != Opcdoes.ATHROW) {

mv.visitVarInsn(Opcodes.ALOAD, 42);

}

}

}

我个人更喜欢AdviceAdapter,因为它消除了对原始返回指令进行实际调用的麻烦,就像你必须使用第一个解决方案一样(例如super.visitInsn(操作码);).其次,它为访问RETURN指令(和ATHORW)提供了一个很好的抽象;这与vanilla MethodVisitor中的visitInsn(int操作码)方法不同,在那里你必须检测RETURN指令在诸如DUP,ICONST_0等许多其他方面的访问,这些访问可能与也可能与此问题无关.手.

但这又取决于手头的问题.如果这是唯一正在执行的仪器,我将坚持使用AdviceAdapter.如果你想要结合访问RETURN指令做其他事情,我可能会继续使用简单的MethodVisitor,因为它可能会给我更大的灵活性.话虽这么说,我一直在使用AdviceAdapter一年多的时间用于重型仪表驱动的项目,到目前为止它已经很好了!

编辑:

应用方法访问者

通常不清楚如何使用或应用方法访问者/方法适配器(至少对我而言),所以我在这里汇总了一个快速代码示例:gist.github.com/VijayKrishna/1ca807c952187a7d8c4d,它显示了如何使用方法适配器,通过它对应的class-visitor / class-adapter.在示例代码段中,我已经从我在此答案中使用的方法更改了方法适配器的名称,但它们执行相同的操作.此外,代码段显示了一个扩展AdviceAdapter的方法适配器.

总之,您首先“调用”类适配器,如下所示:

ClassReader cr = new ClassReader(in);

ClassWriter cw = new ClassWriter(ClassReader.EXPAND_FRAMES);

ReturnAdapter returnAdapter = new ReturnAdapter(cw, className);

cr.accept(returnAdapter, 0);

然后,您可以在类适配器的visitMethod方法中按照以下方法调整方法:

MethodVisitor mv;

mv = cv.visitMethod(access, name, desc, signature, exceptions);

mv = new MethodReturnAdapter(Opcodes.ASM4, className, access, name, desc, mv);

return mv;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值