有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

参数名为w/ClassWriter的java ASM创建方法

Kotlin代码使用org。objectweb。asm库

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,
            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,
            0,
            bytes.count()
    )

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

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

例如,在本例中,创建的类没有参数名(在反编译器中默认为var0),我希望可以保存参数名,比如“args”。可能吗


共 (1) 个答案

  1. # 1 楼答案

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

    最简单的方法就是模拟已编译的类

    我所要做的就是给它贴上标签,然后访问带有名称的局部变量

                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;",
                        null,
                        start,
                        end,
                        0
                )
    
                methodVisitor.visitMaxs(0, 0)
                methodVisitor.visitEnd()