我正在使用 java 工具和 ASM 来操作 java 字节码。我怎么知道一个函数是否是静态的?
我尝试使用 Modifier.isStatic 但我无法在仪器内部运行它。我可以使用 ASM 函数知道这一点吗?
我需要它来获取函数参数。如果函数不是静态的,则 this 对象位于堆栈的索引 0 中
我正在使用 java 工具和 ASM 来操作 java 字节码。我怎么知道一个函数是否是静态的?
我尝试使用 Modifier.isStatic 但我无法在仪器内部运行它。我可以使用 ASM 函数知道这一点吗?
我需要它来获取函数参数。如果函数不是静态的,则 this 对象位于堆栈的索引 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 则该方法是静态的
您可以在覆盖时将访问变量从类访问者传递给您的方法访问者:
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);
}
编写自己的类访问者,然后覆盖“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
}