1

我正在使用 java 工具和 ASM 来操作 java 字节码。我怎么知道一个函数是否是静态的?

我尝试使用 Modifier.isStatic 但我无法在仪器内部运行它。我可以使用 ASM 函数知道这一点吗?

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

4

3 回答 3

0

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

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

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

这将返回方法中的参数数量。由于放入 localVariable 列表的第一个变量是参数,因此提取第一个 [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") 是否为真;如果为真,则该方法是非静态的,反之亦然。如果该方法没有 localVariables 则该方法是静态的

于 2013-11-11T00:10:55.467 回答
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);
    }
于 2020-04-19T17:36:13.850 回答
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
    }
于 2020-11-11T22:50:07.747 回答