通过反射获取方法的参数名称(JDK8以上支持)

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

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

 

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

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.List;

public class ParameterNameUtil {

    public static void main(String[] args) {
        List<String> paramterNames = getParameterNameJava8(
                ParameterNameUtil.class, "getParameterNameJava8");
        paramterNames.forEach((x) -> System.out.println(x));
    }

    public static List<String> getParameterNameJava8(Class clazz, String methodName) {
        List<String> paramterList = new ArrayList<>();
        Method[] methods = clazz.getDeclaredMethods();
        for (Method method : methods) {
            if (methodName.equals(method.getName())) {
                //直接通过method就能拿到所有的参数
                Parameter[] params = method.getParameters();
                for (Parameter parameter : params) {
                    paramterList.add(parameter.getName());
                }
            }
        }
        return paramterList;
    }
}

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

 

  二、通过spring的LocalVariableTableParameterNameDiscoverer获取

    public static void main(String[] args) {
        List<String> paramterNames = getParamterName(ParameterNameUtil.class, "getParamterName");
        paramterNames.forEach((x) -> System.out.println(x));
    }

    public static List<String> getParamterName(Class clazz, String methodName) {
        LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
        Method[] methods = clazz.getDeclaredMethods();
        for (Method method : methods) {
            if (methodName.equals(method.getName())) {
                //获取到该方法的参数们
                String[] params = u.getParameterNames(method);
                return Arrays.asList(params);
            }
        }
        return null;
    }

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

 

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

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

 

IDEA配置方法如下:

  

 

posted @ 2019-01-01 16:02  kancy  阅读(15223)  评论(0编辑  收藏  举报