微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

参数名称为ClassWriter的ASM创建方法

如何解决参数名称为ClassWriter的ASM创建方法

使用org.objectweb.asm库的Kotlin代码

import org.objectweb.asm.ClassWriter
import org.objectweb.asm.Opcodes.*

fun main(args: Array<String>) {
    val classWriter = ClassWriter(ClassWriter.COmpuTE_MAXS)

    classWriter.visit(
            V1_8,ACC_PUBLIC,"com/github/patrick/learnasm/build/HelloWorld",null,"java/lang/Object",null
    )

    val methodVisitor = classWriter.visitMethod(
            ACC_PUBLIC + ACC_STATIC,"main","([Ljava/lang/String;)V",null
    )

    methodVisitor.visitFieldInsn(
            GETSTATIC,"java/lang/System","out","Ljava/io/PrintStream;"
    )

    methodVisitor.visitLdcInsn(
            "Hello World!"
    )

    methodVisitor.visitMethodInsn(
            INVOKEVIRTUAL,"java/io/PrintStream","println","(Ljava/lang/String;)V",false
    )

    methodVisitor.visitInsn(
            RETURN
    )

    methodVisitor.visitMaxs(
            0,0
    )

    methodVisitor.visitEnd()

    val bytes = classWriter.toByteArray()
    val clazz = defineClass(
            "com.github.patrick.learnasm.build.HelloWorld",bytes,bytes.count()
    )

    clazz.getDeclaredMethod("main",Array<String>::class.java).invoke(null,null)
}

我正在尝试学习asm,并且很好奇是否可以创建带有命名参数的方法

例如,在这种情况下,创建的类没有参数名称(在反编译器中认为var0),我希望我可以保存“ args”之类的参数名称。有可能吗?

解决方法

通过查看已编译的类(包括调试信息)来找到答案

简单的方法是仅模拟编译的类

我要做的就是在上面贴上标签,并访问带有名称的局部变量。

            methodVisitor = classWriter.visitMethod(
                    Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC,"main","([Ljava/lang/String;)V",null,null
            )

            methodVisitor.visitParameterAnnotation(
                    0,"Lorg.jetbrains.annotations.NotNull;",false
            )

            val start = Label()
            methodVisitor.visitLabel(start)

            methodVisitor.visitFieldInsn(
                    Opcodes.GETSTATIC,"java/lang/System","out","Ljava/io/PrintStream;"
            )

            methodVisitor.visitLdcInsn("Hello World!")

            methodVisitor.visitMethodInsn(
                    Opcodes.INVOKEVIRTUAL,"java/io/PrintStream","println","(Ljava/lang/String;)V",false
            )

            methodVisitor.visitInsn(Opcodes.RETURN)

            val end = Label()
            methodVisitor.visitLabel(end)

            methodVisitor.visitLocalVariable(
                    "args","[Ljava/lang/String;",start,end,0
            )

            methodVisitor.visitMaxs(0,0)
            methodVisitor.visitEnd()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。