如何使用java检测和ASM知道该方法是否是静态的

时间:2013-10-07 15:42:04

标签: java instrumentation

我使用java instrumentation和ASM来操作java字节码。 我怎么知道函数是否是静态的?

我尝试使用Modifier.isStatic,但我无法在仪器内运行它。 我可以使用ASM功能知道吗?

我需要它来获取函数参数。如果函数不是静态的,则此对象位于堆栈的索引0中

3 个答案:

答案 0 :(得分:0)

我建议查看有问题的MethodNode的localVariableNodes。如果从调用“MethodNodeName”获得的列表中的第一个变量.localVariables是MethodNode所属的类的实例,则MethodNode不是静态的,反之亦然。

要获取方法的参数,请使用此

String raw = Arrays.toString(Type.getArgumentTypes("MethodNodeName".desc));
int numParams = (Arrays.asList(raw.split(",[ ]*"))).size();

这将返回方法中的参数数量。由于放入localVariable列表的第一个变量是params,因此提取第一个[1,numParams]变量来获取参数是一个简单的问题。

例如给定

public void methodName(int arg0, int arg1){ ....}

局部变量列表中的前三个变量将以索引0开头 (“方法属于的类型的对象”,“int类型的对象”,“int类型的对象”,......)

其中

public static void methodName(int arg0, int arg1){ ....}

将产生(“int类型的对象”,“int类型的对象”,...)

请注意,这是假设所讨论的方法不将该方法所属的类的对象作为其第一个参数。

欢呼声

编辑:

作为替代解决方案,您可以检查localVariableNodes.get(0).equals(“this”)是否为true;如果确实如此,则该方法是非静态的,反之亦然。如果该方法没有localVariables,则该方法是静态的

答案 1 :(得分:0)

您可以在覆盖时将访问变量从类访问者传递给方法访问者:

public MethodVisitor visitMethod(int access, String name, String desc,
                                     String signature, String[] exceptions)

如果访问值大于Opcodes.ACC_STATIC,则表明该方法是静态的。

班级访客示例:

public class LogMethodClassVisitor extends ClassVisitor {

    public LogMethodClassVisitor(ClassVisitor cv) {
        super(Opcodes.ASM5, cv);
    }

    @Override
    public MethodVisitor visitMethod(int access, String name, String desc,
                                     String signature, String[] exceptions) {
        MethodVisitor mv = super.visitMethod(access, name, desc, signature,
                exceptions);
        return new LogMethodVisitor(this.api, mv, name, desc, access);
    }
}

MethodVisitorConstructor的示例:

public class LogMethodVisitor extends MethodVisitor {
    private boolean isAnnotationPresent = false;
    private String methodName;
    private String description;
    private boolean isStatic;

    public LogMethodVisitor(int api, MethodVisitor methodVisitor, String methodName, String description, int access) {
        super(api, methodVisitor);
        this.methodName = methodName;
        this.description = description;
        isStatic = (access > Opcodes.ACC_STATIC);
    }

答案 2 :(得分:0)

编写您自己的类访问者,然后覆盖“ visitMethod”

  @Override
    public MethodVisitor visitMethod(int access, String name, String desc,
                                     String signature, String[] exceptions) 
    {
        // for a single flag bit, test against zero is sufficient
        boolean isStatic = (access & Opcodes.ACC_STATIC) != 0;
        // do something else
    }