ASM之ClassWriter生成.class
我们可以使用ClassWriter来生成一个类
如果不知道如何编写ASMified代码,可以直接使用插件ASMPlugin,将你需要的功能编写成正常的java代码,然后使用ASM Bytecode Viewer将编写的类转换成ASMified代码后作为参考
代码如下
package com.example.asmapplicationimport org.junit.Test
import org.objectweb.asm.ClassWriter
import org.objectweb.asm.Opcodes
import java.io.File
import java.io.FileOutputStreamclass DemoASMGenerateClass {@Testfun generate(){val filePath = "E:\\Develop\\ASMApplication2\\app\\src\\test\\java\\com\\example\\asmapplication\\generate\\GenerateTest.class"val file = File(filePath)if (!file.parentFile.exists()){file.parentFile.mkdir()}//创建ClassWriterval cw = ClassWriter(ClassWriter.COMPUTE_FRAMES)//设定包名和类名cw.visit(Opcodes.V1_8,Opcodes.ACC_PUBLIC,"com/example/asmapplication/generate/GenerateTest",null,"java/lang/Object",null)//每个classFile都有一个<init>的初始化方法val mvInit = cw.visitMethod(Opcodes.ACC_PUBLIC,"<init>","()V",null,null)mvInit.visitCode()mvInit.visitVarInsn(Opcodes.ALOAD, 0)mvInit.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false)mvInit.visitInsn(Opcodes.RETURN)mvInit.visitMaxs(1, 1);mvInit.visitEnd()//创建一个test()方法val mvTest = cw.visitMethod(Opcodes.ACC_PUBLIC,"test","()V",null,null)mvTest.visitCode()//打印Hello WordmvTest.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()}
}
最终生成代码:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//package com.example.asmapplication.generate;public class GenerateTest {public GenerateTest() {}public void test() {System.out.println("Hello Word!!!");}
}