Java : Javassist获取方法的参数名称

 1 private static List<String> getParamNames(String methodName, Class<?> clazz) {
 2         List<String> paramNames = new ArrayList<>();
 3         ClassPool pool = ClassPool.getDefault();
 4         try {
 5             CtClass ctClass = pool.getCtClass(clazz.getName());
 6             CtMethod ctMethod = ctClass.getDeclaredMethod(methodName);
 7             // 使用javassist的反射方法的参数名
 8             javassist.bytecode.MethodInfo methodInfo = ctMethod.getMethodInfo();
 9             CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
10             LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag);
11             if (attr != null) {
12                 int len = ctMethod.getParameterTypes().length;
13                 // 非静态的成员函数的第一个参数是this
14                 int pos = Modifier.isStatic(ctMethod.getModifiers()) ? 0 : 1;
15                 for (int i = 0; i < len; i++) {
16                     paramNames.add(attr.variableName(i + pos));
17                 }
18 
19             }
20             return paramNames;
21         } catch (NotFoundException e) {
22             e.printStackTrace();
23             return null;
24         }
25     }

这是一个使用Javassist获取方法参数名称的函数, 正常情况下执行是没什么问题的, 但如果在编译的时候加入 -g:none, 那么第10行则获取不到任何本地变量的信息.

-g参数的意义, 参考这个链接 https://blog.csdn.net/shenzhang/article/details/84399565

所有编译相关参数可以参考 https://blog.csdn.net/centurymagus/article/details/2097036

简单来说-g参数编译之后可以把方法的变量名称等一起保存在class文件中, 这也是为什么Debug的时候可以查看变量的信息.(加入 -g:none编译出来的文件不能进行Debug,命中不了任何断点)

下面是测试截图:

源码(可以看到after方法里有个变量名称为object):

 

 使用-g编译生成的class文件:

使用-g:none编译生成的class文件:

 

 

所以, springMVC等框架的处理方法一般是根据参数的类型来注入方法参数并invoke调用, 当然可能也支持使用变量名称, 但是加入-g:none可能会失效, 所以可以借助注解 @RequestParam等来指定名称

posted @ 2020-09-18 15:26  cccy0  阅读(2046)  评论(0编辑  收藏  举报