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

如何使用 org.objectweb.asm.MethodVisitor 获取方法参数的数量和类型?

如何解决如何使用 org.objectweb.asm.MethodVisitor 获取方法参数的数量和类型?

我正在尝试使用 asm MethodVisitor 从 Java 类字节码中提取方法参数信息。不调用 visitParameterMethodVisitor 方法(因为编译的类文件中不存在参数名称)。如何获取方法参数及其类型的数量

到目前为止,我唯一发现的是 descvisitMethodMethodVisitor 参数。我可以从 asm-util 复制粘贴 TraceSignatureVisitor 类,重写大约 50 行代码以将参数声明存储到 List/array 而不是单个 StringBuffer

在回答“https://stackoverflow.com/questions/18061588/get-function-arguments-values-using-java-asm-for-bytecode-instrimentation”中建议了另一个选项:

可以使用以下要点中的代码方法描述中计算方法的参数数量https://gist.github.com/VijayKrishna/6160036。使用 parseMethodArguments(String desc) 方法,您可以轻松计算方法的参数数量

在我看来,复制粘贴和重写 TraceSignatureVisitor 仍然更好。

但我想应该更简单的方法来处理 asm-util 中的方法签名。有吗?

解决方法

ASM 有一个用于此目的的摘要,Type

Type 的实例可以表示原始类型、引用类型或方法类型。所以你可以先从描述符字符串中得到一个表示方法类型的类型,然后查询它的参数类型和返回类型。

String desc = "(Ljava/lang/String;I[[ZJ)D";

Type methodType = Type.getMethodType(desc);
int sizes = methodType.getArgumentsAndReturnSizes();
System.out.println("return type: "
    + methodType.getReturnType().getClassName() + " (" +(sizes & 3) + ')');

Type[] argTypes = methodType.getArgumentTypes();
System.out.println(argTypes.length + " arguments (" + (sizes >> 2) + ')');
for (int ix = 0; ix < argTypes.length; ix++) {
    System.out.println("arg" + ix + ": " + argTypes[ix].getClassName());
}

getArgumentsAndReturnSizes() 返回的大小是指局部变量和操作数堆栈条目,其中 longdouble 算作两个。它还考虑了隐含的 this 参数,这对于实例方法来说很方便,但需要调用者为 static 方法减去一个。

示例打印

return type: double (2)
4 arguments (6)
arg0: java.lang.String
arg1: int
arg2: boolean[][]
arg3: long

如果您只对其中一项功能感兴趣,可以使用 Type 类的静态方法之一直接获取它。

int sizes = Type.getArgumentsAndReturnSizes(desc);
Type ret = Type.getReturnType(desc);
Type[] argTypes = Type.getArgumentTypes(desc);

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