ASM之MethodWriter创建静态方法

ASM之MethodWriter创建静态方法

ASM创建静态方法和创建方法基本类似,都是使用 ClassWriter.visitMethod() 来实现,区别是传入的access参数变为Opcodes.*ACC_PUBLIC* + Opcodes.*ACC_STATIC*

示例代码如下

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 ASMGenerateStaticMethod {
    @Test
    fun test() {
        val filePath =
            "E:\\Develop\\ASMApplication2\\app\\src\\test\\java\\com\\example\\asmapplication\\generate\\GenerateStaticMethod.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/GenerateStaticMethod",
            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 + Opcodes.ACC_STATIC, "test", "()V", null, null)
        mvTest.visitCode()
        //打印Hello World
        mvTest.visitLdcInsn("Hello World!!!")
        mvTest.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;")
        mvTest.visitInsn(Opcodes.SWAP)
        mvTest.visitMethodInsn(
            Opcodes.INVOKEVIRTUAL,
            "java/io/PrintStream",
            "println",
            "(Ljava/lang/Object;)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.GenerateStaticMethod")
        clazz.getMethod("test").invoke(null)
    }
}

最终生成代码:

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

package com.example.asmapplication.generate;

public class GenerateStaticMethod {
    public GenerateStaticMethod() {
    }

    public static void test() {
        System.out.println("Hello World!!!");
    }
}

你可能感兴趣的:(java,ASM)