使用org.objectweb.asm无法读取-parameters编译的参数名是什么原因?
ASM读取-parameters编译参数生成的参数名问题说明
根本原因
你调用的MethodNode.localVariables属性对应Class文件中的LocalVariableTable调试表,该表仅当编译时添加-g:vars参数才会生成,和javac -parameters生成的参数名属于完全不同的存储结构,你读取的目标属性有误。
-parameters编译参数生成的参数名,存储在Class文件方法的MethodParameters属性中,该属性是Java 8引入的标准属性,不依赖调试信息开关,也是Java反射能读取到参数名的来源,该属性不会被写入localVariables中。
ASM正确读取方案
- 确保你使用的ASM版本不低于5.0,该版本才开始支持Java 8新增的
MethodParameters属性解析 - 无需读取
localVariables,直接读取MethodNode的parameters属性即可,该属性为List<ParameterNode>类型,每个ParameterNode实例的name字段就是你需要的参数名,access字段还可以获取参数的修饰符信息 - 解析类字节码时,
ClassReader.accept方法不要传入SKIP_DEBUG标识,否则会跳过MethodParameters属性的解析,导致返回null
代码示例
// 读取目标类字节码 ClassReader classReader = new ClassReader(targetClassBytes); ClassNode classNode = new ClassNode(); // 传入0表示解析所有属性,不要加SKIP_DEBUG classReader.accept(classNode, 0); for (MethodNode method : classNode.methods) { System.out.println("当前方法名:" + method.name); for (ParameterNode param : method.parameters) { System.out.println("参数名:" + param.name); } }
内容的提问来源于stack exchange,提问作者majakthecoder
相关产品推荐
相关产品推荐

