博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用ASM获得JAVA类方法参数名
阅读量:4309 次
发布时间:2019-06-06

本文共 3367 字,大约阅读时间需要 11 分钟。

在Java1.8之后,可以通过反射API java.lang.reflect.Executable.getParameters来获取到方法参数的元信息,

(在使用编译器时加上-parameters参数,它会在生成的.class文件中额外存储参数的元信息)
但是在JDK1.7及以下版本的API并不能获取到函数的参数名称,这时候可以使用字节码工具ASM来实现这一功能.

package yyl.example.demo.asm;import java.io.IOException;import java.lang.reflect.Method;import java.lang.reflect.Modifier;import java.util.Arrays;import org.objectweb.asm.ClassAdapter;import org.objectweb.asm.ClassReader;import org.objectweb.asm.ClassWriter;import org.objectweb.asm.Label;import org.objectweb.asm.MethodAdapter;import org.objectweb.asm.MethodVisitor;import org.objectweb.asm.Type;/** * 使用ASM获得JAVA类方法参数名 */public class GetMethodParamNameTest {    static class Test {        void method(String name, Object value) {        }    }    public static void main(String[] args) throws SecurityException, NoSuchMethodException, IOException {        Method method1 = Test.class.getDeclaredMethod("method", String.class, Object.class);       System.out.println(Arrays.toString(getMethodParamNames(method)));    }/** 使用字节码工具ASM来获取方法的参数名 */    public static String[] getMethodParamNames(final Method method) throws IOException {        final String methodName = method.getName();        final Class
[] methodParameterTypes = method.getParameterTypes(); final int methodParameterCount = methodParameterTypes.length; final String className = method.getDeclaringClass().getName(); final boolean isStatic = Modifier.isStatic(method.getModifiers()); final String[] methodParametersNames = new String[methodParameterCount]; ClassReader cr = new ClassReader(className); ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); cr.accept(new ClassAdapter(cw) { public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); final Type[] argTypes = Type.getArgumentTypes(desc); //参数类型不一致 if (!methodName.equals(name) || !matchTypes(argTypes, methodParameterTypes)) { return mv; } return new MethodAdapter(mv) { public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) { //如果是静态方法,第一个参数就是方法参数,非静态方法,则第一个参数是 this ,然后才是方法的参数 int methodParameterIndex = isStatic ? index : index - 1; if (0 <= methodParameterIndex && methodParameterIndex < methodParameterCount) { methodParametersNames[methodParameterIndex] = name; } super.visitLocalVariable(name, desc, signature, start, end, index); } }; } }, 0); return methodParametersNames; } /** * 比较参数是否一致 */ private static boolean matchTypes(Type[] types, Class
[] parameterTypes) { if (types.length != parameterTypes.length) { return false; } for (int i = 0; i < types.length; i++) { if (!Type.getType(parameterTypes[i]).equals(types[i])) { return false; } } return true; }}

 

备注:JDK 自带类 ,接口方法和抽象方法无法使用这种方式获取参数名

转载于:https://www.cnblogs.com/relucent/p/6525821.html

你可能感兴趣的文章
vue+springboot打包发布
查看>>
XSL 开发总结
查看>>
【NOI 2018】归程(Kruskal重构树)
查看>>
如何开始DDD(完)
查看>>
[svc]gns3模拟器及探讨几个bgp问题
查看>>
Error:fatal: Not a git repository (or any of the parent directories): .git
查看>>
15 可视化工具 Navicat的简单使用
查看>>
神兵利器:Burpsuite工具分享与使用简介
查看>>
xml
查看>>
使用 Left Join 的一个错误说明
查看>>
Scala入门系列(十一):模式匹配
查看>>
Sql Server 生成数据透视表 (行列转换等经典SQL语句)
查看>>
理解sizeof()
查看>>
Vue学习笔记之vue-cli脚手架安装和webpack-simple模板项目生成
查看>>
SqlServer 扩展属性
查看>>
优先队列
查看>>
一些程序和工具
查看>>
java8 运算语法集
查看>>
IDEA关于重命名
查看>>
Es6 中let var和 const 了解
查看>>