方法的参数名,在很多时候我们是需要反射得到的。但是在java8之前,代码编译为class文件后,方法参数的类型是固定的,但参数名称却丢失了,这和动态语言严重依赖参数名称形成了鲜明对比。(java是静态语言,所以入参名称叫什么其实无所谓的)。

  虽然名称无所谓,但很多时候,我们需要此名称来做更好的安排,比如Myabtis的应用。下面介绍两种方式获取参数名:

  一、通过jdk原生反射机制获取

  1. import java.lang.reflect.Method;
  2. import java.lang.reflect.Parameter;
  3. import java.util.ArrayList;
  4. import java.util.List;
  5.  
  6. public class ParameterNameUtil {
  7.  
  8. public static void main(String[] args) {
  9. List<String> paramterNames = getParameterNameJava8(
  10. ParameterNameUtil.class, "getParameterNameJava8");
  11. paramterNames.forEach((x) -> System.out.println(x));
  12. }
  13.  
  14. public static List<String> getParameterNameJava8(Class clazz, String methodName) {
  15. List<String> paramterList = new ArrayList<>();
  16. Method[] methods = clazz.getDeclaredMethods();
  17. for (Method method : methods) {
  18. if (methodName.equals(method.getName())) {
  19. //直接通过method就能拿到所有的参数
  20. Parameter[] params = method.getParameters();
  21. for (Parameter parameter : params) {
  22. paramterList.add(parameter.getName());
  23. }
  24. }
  25. }
  26. return paramterList;
  27. }
  28. }

Java 8开始增加了类Parameter,在class文件中保留参数名,给反射带来了极大的便利。

  二、通过spring的LocalVariableTableParameterNameDiscoverer获取

  1. public static void main(String[] args) {
  2. List<String> paramterNames = getParamterName(ParameterNameUtil.class, "getParamterName");
  3. paramterNames.forEach((x) -> System.out.println(x));
  4. }
  5.  
  6. public static List<String> getParamterName(Class clazz, String methodName) {
  7. LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
  8. Method[] methods = clazz.getDeclaredMethods();
  9. for (Method method : methods) {
  10. if (methodName.equals(method.getName())) {
  11. //获取到该方法的参数们
  12. String[] params = u.getParameterNames(method);
  13. return Arrays.asList(params);
  14. }
  15. }
  16. return null;
  17. }

备注:如果不用Class,而是通过spring注入的实例,然后instance.getClass.getDeclaredMethods()则无法得到参数名,调试时看到方法名称是通过jdk代理过的,拿不到参数名。

 另外,能成功获取方法参数的名称需要满足两个条件:

  1. JDK版本必须是1.8及以上
  2. 编译时候必须有编译选项:javac -parameters打开,默认是关闭的

IDEA配置方法如下:

  

通过反射获取方法的参数名称(JDK8以上支持)的更多相关文章

  1. java reflect反射获取方法变量参数

    类的成员包含变量(Field),方法(Method),构造器(Constructor) 类定义 package Reflect; public class MyTest { public int a; ...

  2. Spring AOP获取方法的参数名称和参数值

    aop配置: <aop:aspectj-autoproxy expose-proxy="true" /> @Before(value = "execution ...

  3. C# 获取方法内参数名称

    public partial class Main : Form { public Main() { foreach(var parameter in typeof(Main).GetMethod(& ...

  4. Spring LocalVariableTableParameterNameDiscoverer获取方法的参数名

    Spring LocalVariableTableParameterNameDiscoverer获取方法的参数名 问题:Java.lang.reflect 包中提供了很多方法,获取所有的方法,获取所有 ...

  5. <经验杂谈>C#中一种最简单、最基本的反射(Reflection):通过反射获取方法函数

    说起反射之前和很多用C#/.net的同仁们一样,相比于一般应用层对数据的增删改查总有点觉得深奥到难以理解.其实程序这东西,用过.实践过就很简单,我一直这么认为. 先说下概念:反射 Reflection ...

  6. Spring AOP获取拦截方法的参数名称跟参数值

    注意:这种方式需要JDK1.8版本支持 开始:http://www.cnblogs.com/wing7319/p/9592184.html 1.aop配置: <aop:aspectj-autop ...

  7. C#通过反射获取类中的方法和参数个数,反射调用方法带参数

    using System; using System.Reflection; namespace ConsoleApp2 { class Program { static void Main(stri ...

  8. C# 通过反射获取方法/类上的自定义特性

    1.所有自定义属性都必须继承System.Attribute 2.自定义属性的类名称必须为 XXXXAttribute 即是已Attribute结尾 自定义属性QuickWebApi [Attribu ...

  9. C# 反射获取属性值、名称、类型以及集合的属性值、类型名称

    实体类 class Product { public string Id { get; set; } public string Name { get; set; } public List<P ...

随机推荐

  1. SpringBoot与数据源

    1.JDBC <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...

  2. 纯css实现手机通讯录

    我们经常在手机上看到通讯录列表,这类布局一般有两个显著的效果 首字母吸顶 快速定位 下面我们来实现一下 页面结构 这里页面结构很简单,就是两个列表 <div class="con&qu ...

  3. php正则匹配汉字提取其它信息剔除和验证邮箱

    正则匹配汉字提取其它信息剔除demo <?php //提取字符串中的汉字其余信息剔除 $str='te,st 测 .试,.,.?!::·…~&@#,.?!:;.……-&@#“” ...

  4. 如何实现免登陆功能(cookie session?)

    Cookie的机制 Cookie是浏览器(User Agent)访问一些网站后,这些网站存放在客户端的一组数据,用于使网站等跟踪用户,实现用户自定义功能. Cookie的Domain和Path属性标识 ...

  5. 常用模块random/os/sys/time/datatime/hashlib/pymysql等

    一.标准模块 1.python自带的,import random,json,os,sys,datetime,hashlib等 ①.正常按照命令:打开cmd,执行:pip install rangdom ...

  6. JAVA AOP面向切面编程与动态代理

    1.静态代理和动态代理的概念:   在我的另一篇博文:Java 静态代理和动态代理 中有讲到,这里就不做赘述了. JDK动态代理它的好处理是可以为我们生成任何一个接口的代理类,并将需要增强的方法织入到 ...

  7. HIbernate入门3

    HIbernate的一对多操作: 1. 创建实体类:一个Customer类(客户类)和一个LinkMan类(联系人),两者的关系为:一个客户中可能有多个联系人(关于一对多的实体类之间的关联,不做详细介 ...

  8. [Python3 填坑] 018 组装类的几个例子

    目录 1. print( 坑的信息 ) 2. 开始填坑 2.1 MetaClass 举例 2.2 type 举例 2.3 MetaClass 举例 1. print( 坑的信息 ) 挖坑时间:2019 ...

  9. Java 中的 T,E,K,V, 别傻傻分不清楚!

    作者:glmapper https://juejin.im/post/5d5789d26fb9a06ad0056bd9 前言 Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛 ...

  10. [2019杭电多校第五场][hdu6630]permutation 2

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6630 题意为求出1-n,n个数的全排列中有多少种方案满足第一位为x,第n位为y,且相邻数字绝对值之差不 ...