ASM之MethodWriter创建方法并支持传参

ASM之MethodWriter创建方法并支持传参

这里我们除了创建了一个方法,并且在里面加入了函数参数和max计算传入参数谁更大的代码

代码如下:

package com.example.asmapplication

import org.junit.Test
import org.objectweb.asm.ClassWriter
import org.objectweb.asm.Opcodes
import java.io.File
import java.io.FileOutputStream
import java.net.URLClassLoader

class ASMGenerateArgMethod {

    @Test
    fun generate(){
        val filePath = "E:\\Develop\\ASMApplication2\\app\\src\\test\\java\\com\\example\\asmapplication\\generate\\GenerateArgMethod.class"
        val file = File(filePath)
        if (!file.parentFile.exists()){
            file.parentFile.mkdir()
        }
        //创建ClassWriter
        val cw = ClassWriter(ClassWriter.COMPUTE_FRAMES)
        //设定包名和类名
        cw.visit(
            Opcodes.V1_8,
            Opcodes.ACC_PUBLIC,"com/example/asmapplication/generate/GenerateArgMethod",null,"java/lang/Object",null)
        //每个classFile都有一个的初始化方法
        val mvInit = cw.visitMethod(Opcodes.ACC_PUBLIC,"","()V",null,null)
        mvInit.visitCode()
        mvInit.visitVarInsn(Opcodes.ALOAD, 0)
        mvInit.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "", "()V", false)
        mvInit.visitInsn(Opcodes.RETURN)
        mvInit.visitMaxs(1, 1);
        mvInit.visitEnd()
        //创建一个test()方法
        val mvTest = cw.visitMethod(Opcodes.ACC_PUBLIC,"test","(II)V",null,null)
        mvTest.visitCode()
        mvTest.visitVarInsn(Opcodes.ILOAD, 1)
        mvTest.visitVarInsn(Opcodes.ILOAD, 2)
        mvTest.visitMethodInsn(Opcodes.INVOKESTATIC,"java/lang/Math", "max", "(II)I", false)
        mvTest.visitVarInsn(Opcodes.ISTORE,3)
        mvTest.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;")
        mvTest.visitVarInsn(Opcodes.ILOAD,3)
        mvTest.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(I)V", false)
        mvTest.visitInsn(Opcodes.RETURN)
        mvTest.visitMaxs(2, 1)
        mvTest.visitEnd()
        //类的访问结束
        cw.visitEnd()
        //输出为class文件
        val outputStream = FileOutputStream(file)
        outputStream.write(cw.toByteArray())
        outputStream.flush()
        outputStream.close()
        val classLoader = URLClassLoader(
            arrayOf(
                File("E:\\Develop\\ASMApplication2\\app\\src\\test\\java").toURI().toURL()
            )
        )
        val clazz =
            classLoader.loadClass("com.example.asmapplication.generate.GenerateArgMethod")
        val obj = clazz.newInstance()
        clazz.getMethod("test",Int::class.java,Int::class.java).invoke(obj,1,2)
    }
}

生成的代码如下

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.example.asmapplication.generate;

public class GenerateArgMethod {
    public GenerateArgMethod() {
    }

    public void test(int var1, int var2) {
        int var3 = Math.max(var1, var2);
        System.out.println(var3);
    }
}

你可能感兴趣的:(开发语言,java)