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等来指定名称