首页 / JAVA / ASM Java替换方法调用指令
ASM Java替换方法调用指令
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了ASM Java替换方法调用指令,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3598字,纯文字阅读大概需要6分钟。
内容图文
![ASM Java替换方法调用指令](/upload/InfoBanner/zyjiaocheng/754/cadd19fea7194bbeb3c55e1e35520898.jpg)
背景
我想使用ASM Java框架对一些耗时的方法(如org / json / JSONObject.toString())进行一些检测工作.
原始调用方法
public class JSONUsage {
public void callToString() {
JSONObject jsonObject = new JSONObject();
String a = jsonObject.toString();//original call
System.out.println(a);
}
}
仪表后
public class JSONUsage {
public void callToString() {
JSONObject jsonObject = new JSONObject();
// **important!**
//pass the instance as an param, replace the call to a static method
String a = JSONReplacement.jsonToString(jsonObject);
System.out.println(a);
}
}
public class JSONReplacement {
public static String jsonToString(JSONObject jsonObject) {
//do the time caculation
long before = System.currentTimeMillis();
String ret = jsonObject.toString();
long elapsed = System.currentTimeMillis() - before;
return ret;
}
}
使用ASM框架3.0
ClassReader cr = new ClassReader("JSONUsage");
ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES);
ReplaceClassVisitor replaceClassVisitor = new ReplaceClassVisitor(cw);
cr.accept(replaceClassVisitor, ClassReader.EXPAND_FRAMES);
问题:如何使用ASM API获得一般溶剂?
public class ReplaceClassVisitor extends ClassAdapter {
public ReplaceClassVisitor(ClassVisitor cv) {
super(cv);
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
return new MethodReplaceMethodVisitor(super.visitMethod(access, name, desc, signature, exceptions), access, name, desc);
}
private static final class MethodReplaceMethodVisitor extends GeneratorAdapter {
public MethodReplaceMethodVisitor(MethodVisitor mv, int access, String name, String desc) {
super(mv, access, name, desc);
}
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc) {
//org/json/JSONObject.toString() here is a example,
//i want a general instruction
if (owner.equals("org/json/JSONObject") && name.equals("toString")) {
replaceCall(opcode, owner, name, desc);
}
}
private void replaceCall(int opcode, String owner, String name, String desc) {
//how can i have a general asm instruction to manipulate this method call?
}
}
}
解决方法:
您不需要“操纵”方法调用.关键点在于,您的访问者通过将每个传入的访问者呼叫转发给编写者来生成代码,并且您可以方便地继承执行此操作的实现1:1.
所以每次访问…你没有覆盖的方法会将每次调用委托给编写器,产生完全相同的指令.当它们委托给传递相同参数的原始超级实现时,这同样适用于重写方法.当您重写方法并且不中继调用时,不会再现,读取和删除相应的指令.当您调用其他访问…方法(而不是)时,您将生成其他指令.
private static final class MethodReplaceMethodVisitor extends GeneratorAdapter {
public MethodReplaceMethodVisitor(
MethodVisitor mv, int access, String name, String desc) {
super(mv, access, name, desc);
}
@Override
public void visitMethodInsn(
int opcode, String owner, String name, String desc, boolean itf) {
if(opcode==Opcodes.INVOKEVIRTUAL && owner.equals("org/json/JSONObject")
&& name.equals("toString") && desc.equals("()Ljava/lang/String;")) {
// not relaying the original instruction to super effectively removes the original
// instruction, instead we're producing a different instruction:
super.visitMethodInsn(Opcodes.INVOKESTATIC, "whatever/package/JSONReplacement",
"jsonToString", "(Lorg/json/JSONObject;)Ljava/lang/String;", false);
}
else // relaying to super will reproduce the same instruction
super.visitMethodInsn(opcode, owner, name, desc, itf);
}
// all other, not overridden visit methods reproduce the original instructions
}
因此上面的代码拦截了您感兴趣的指令,并且不会重现它,而是生成所需的invokestatic指令.这没有额外的调整,因为静态方法调用将从堆栈中使用JSONObject并生成一个String,就像原始调用一样,因此对周围的代码没有任何影响.
内容总结
以上是互联网集市为您收集整理的ASM Java替换方法调用指令全部内容,希望文章能够帮你解决ASM Java替换方法调用指令所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。