








import org.objectweb.asm.*;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.invoke.*;
// 假设的用户类
class UserClass {
public String test(int param) {
System.out.println("Test method is called with param: " + param);
return "Result from test method";
}
}
public class InvokeTestWithParamsAndReturnGenerator {
public static CallSite bootstrap(MethodHandles.Lookup lookup, String name, MethodType type, String descIdent, Object objVal) throws Throwable {
Class<?> clazz = Class.forName(descIdent);
// 根据实际的参数和返回值类型构建 MethodType
MethodType methodType = MethodType.methodType(String.class, int.class);
MethodHandle mh = lookup.findVirtual(clazz, name, methodType);
return new ConstantCallSite(mh.bindTo(objVal));
}
public static void main(String[] args) throws IOException {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, "InvokeTestWithParamsAndReturn", null, "java/lang/Object", null);
// 生成 main 方法
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
mv.visitCode();
// 创建 FObj 实例并存储 UserClass 实例
mv.visitTypeInsn(Opcodes.NEW, "com/faros/lib/typeobj/FObj");
mv.visitInsn(Opcodes.DUP);
// 创建 UserClass 实例
mv.visitTypeInsn(Opcodes.NEW, "UserClass");
mv.visitInsn(Opcodes.DUP);
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "UserClass", "<init>", "()V", false);
// 调用 FObj 的 fUObj 静态方法创建 FObj 实例
mv.visitLdcInsn("UserClass");
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "com/faros/lib/typeobj/FObj", "fUObj", "(Ljava/lang/Object;Ljava/lang/String;)Lcom/faros/lib/typeobj/FObj;", false);
// 现在栈顶是 FObj 实例,通过 invokedynamic 调用其存储对象的 test 方法
// 获取 FObj 中的 objVal
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitFieldInsn(Opcodes.GETFIELD, "com/faros/lib/typeobj/FObj", "objVal", "Ljava/lang/Object;");
// 获取 FObj 中的 descIdent
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitFieldInsn(Opcodes.GETFIELD, "com/faros/lib/typeobj/FObj", "descIdent", "Ljava/lang/String;");
// 准备 test 方法的参数
mv.visitLdcInsn(10); // 假设参数为 10
Handle bootstrapMethod = new Handle(
Opcodes.H_INVOKESTATIC,
"InvokeTestWithParamsAndReturnGenerator",
"bootstrap",
"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/invoke/CallSite;",
false
);
// 指定 invokedynamic 指令的方法类型,与 test 方法的参数和返回值匹配
mv.visitInvokeDynamicInsn(
"test",
"(Ljava/lang/Object;Ljava/lang/String;I)Ljava/lang/String;",
bootstrapMethod,
"descIdent",
"objVal"
);
// 处理返回值,这里简单打印
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/String", "toString", "()Ljava/lang/String;", false);
mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
mv.visitInsn(Opcodes.SWAP);
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
mv.visitInsn(Opcodes.RETURN);
mv.visitMaxs(0, 0);
mv.visitEnd();
cw.visitEnd();
// 输出字节码到文件
try (FileOutputStream fos = new FileOutputStream("InvokeTestWithParamsAndReturn.class")) {
fos.write(cw.toByteArray());
}
}
}
Rust编程语言群 1036955113
java新手自学群 626070845
java/springboot/hadoop/JVM 群 4915800
Hadoop/mongodb(搭建/开发/运维)Q群481975850
GOLang Q1群:6848027
GOLang Q2群:450509103
GOLang Q3群:436173132
GOLang Q4群:141984758
GOLang Q5群:215535604
C/C++/QT群 1414577
单片机嵌入式/电子电路入门群群 306312845
MUD/LIB/交流群 391486684
Electron/koa/Nodejs/express 214737701
大前端群vue/js/ts 165150391
操作系统研发群:15375777
汇编/辅助/破解新手群:755783453
大数据 elasticsearch 群 481975850
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。