如何使用ASM为数组中的每个String调用一个函数

时间:2017-10-31 00:16:46

标签: java bytecode

所以我试图使用ASM构建一个字符串数组,但是我想为数组中的每个字符串调用一个函数。我无法弄清楚如何做到这一点,现在已经在互联网上搜索了一段时间。这是我到目前为止构建数组的原因:

InstructionAdapter builder = new InstructionAdapter(mv);
builder.iconst(strings.length);
builder.newarray(Type.getType(String.class));
for (int i = 0; i < strings.length; i++) {
    builder.dup();
    builder.iconst(i);
    builder.aconst(strings[i]);
    builder.astore(InstructionAdapter.OBJECT_TYPE);
}
builder.putstatic(callOwner.name, FIELD_NAME, "[Ljava/lang/String;");

正如你所看到我有一个字符串数组,称为strings,我迭代并构建数组。

这将生成一个可能如下所示的数组

private String[] somearray = { "Test" };

现在我要做的是在数组中的每个字符串上调用一个函数,比如说我有一个名为decode的函数,我将它称为decode("Test")。所以我希望数组看起来像这样

private String[] somearray = { decode("Test") };

如何在数组中的每个元素上调用decode?

1 个答案:

答案 0 :(得分:1)

只要加载要存储在数组中的值,就可以插入操作码。使用您在问题中发布的代码,它应该看起来像这样,假设解码是MyClass中定义的静态方法。

for (int i = 0; i < strings.length; i++) {
    builder.dup();
    builder.iconst(i);
    builder.aconst(strings[i]);
    builder.invokestatic("LMyClass;", "decode", "(Ljava/lang/String;)Ljava/lang/String;", false);
    builder.astore(InstructionAdapter.OBJECT_TYPE);
}

当然,只有当你想在运行时发生decode()调用时才会这样。由于您仅在此处理常量字符串,因此您可能需要考虑在转换时执行解码调用,并仅将结果写入已转换的类文件。在这种情况下,您的代码将看起来像这样。

for (int i = 0; i < strings.length; i++) {
    builder.dup();
    builder.iconst(i);
    builder.aconst(decode(strings[i]));
    builder.astore(InstructionAdapter.OBJECT_TYPE);
}