Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用ASM获取方法参数_Java_Reflection_Java Bytecode Asm - Fatal编程技术网

Java 使用ASM获取方法参数

Java 使用ASM获取方法参数,java,reflection,java-bytecode-asm,Java,Reflection,Java Bytecode Asm,我找到了一些示例,它们使用MethodAdapter向我显示了某些方法调用的位置: public void visitMethodInsn(int opcode, String owner, String name, String desc) { if (owner.equals(targetClass) && name.equals(targetMethod.getName()) &&

我找到了一些示例,它们使用
MethodAdapter
向我显示了某些方法调用的位置:

public void visitMethodInsn(int opcode, String owner, String name, String desc) {
        if (owner.equals(targetClass)
                && name.equals(targetMethod.getName())
                && desc.equals(targetMethod.getDescriptor())) {
            callsTarget = true;
        }
  }
我需要参数,例如,如果我有
object.getText(“mykey”)
我想得到文本“mykey”

这可能吗?

我有一个你可能会觉得有用的工具(特别是,
procyon编译器工具
)。它将使您能够以比ASM更面向对象的方式来执行您的请求。但是,该项目仍处于开发早期,可能会发生变化,因此我不建议在生产项目中使用它

您可以将此作为起点:

public class CallInspectionSample {
    static class Target {
        public static void main(String[] args) {
            new Target().getText("MyKey");
        }

        public String getText(final String key) {
            return null;
        }
    }

    public static void main(String[] args) {
        final TypeReference targetType = MetadataSystem.instance().lookupType("CallInspectionSample$Target");
        final TypeDefinition resolvedType = targetType.resolve();
        final MethodDefinition mainMethod = resolvedType.getDeclaredMethods().get(1);
        final MethodDefinition getTextMethod = resolvedType.getDeclaredMethods().get(2);

        final MethodBody mainBody = mainMethod.getBody();

        final Block methodAst = new Block();
        final DecompilerContext context = new DecompilerContext();

        context.setCurrentType(resolvedType);
        context.setCurrentMethod(mainMethod);

        methodAst.getBody().addAll(AstBuilder.build(mainBody, true, context));

        AstOptimizer.optimize(context, methodAst);

        for (final Expression e : methodAst.getChildrenAndSelfRecursive(Expression.class)) {
            if (e.getCode() == AstCode.InvokeVirtual &&
                ((MethodReference) e.getOperand()).resolve() == getTextMethod) {

                // Analyze arguments here (skip first for instance methods)...
                System.out.println(e.getArguments());
            }
        }
    }
}

(示例输出
[initobject:Target(Target::),ldc:String(“MyKey”)]

似乎我必须使用visitLdcInsn来收集参数。这是一件相对困难的事情,尽管在某些情况下确实有效。问题是,您最终必须分析整个程序,以找出值最初来自何处,以及它是如何从一个字段移动到另一个字段的,等等。但幸运的是,有一些东西可以让您开始。请看第8章。ASM文档中的方法分析。好运气如果你有
object.getText(foo)
,你想要什么?