java反射获取到接口和类的方法对应的参数名称(非参数类型)

假设有方法:     

 String adminTest(String mobile,int age);

希望获取到参数名称:     [mobile,age]

java反射提供了很多方法,获取所有的方法,获取所有的参数类型等,但是却没有一个方法能够帮助我们获取方法的参数名列表。

首先:

  为什么我们需要获取到方法对应的参数名称?    

原因是例如mybatis的mapper接口中定义了很多参数名称,在xml用占位符来标识,就可以类似通过这种方法来一一对应,

包括spring的参数解析,这个问题是我在参考别人的手写mybatis,中考虑到的一个问题,故贴出我查阅资料得到的方法,网上的大部分只能获取到类的方法的参数名称列表,对接口的方法参数名称获取较少.

 

其实也是基于spring中提供的类来实现的:需要jdk1.8及其以上:

在Java1.8之后,可以通过反射API java.lang.reflect.Executable.getParameters来获取到方法参数的元信息。这要求在使用编译器时加上-parameters参数,它会在生成的.class文件中额外存储参数的元信息,这会增加class文件的大小。
 

idea默认是开启的:

 

工具类:

 

 

 

package com.wm.ruanyan1.util;

import com.wm.ruanyan1.service.AdminService;
import com.wm.ruanyan1.service.UserService;
import com.wm.ruanyan1.service.impl.UserServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.util.Assert;

import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * @author 半卷流年
 * @date 2020-6-20 10:12
 */
@Slf4j
public class ReflectUtil {


    /**
     * 借助spring 的工具类,注意需要jdk8及其以上
     * 获取方法的参数的名称(不是类型),这个兼容接口(可以没有实现类)  和 普通类的方法参数
     *
     * 例如:    public String test(String name,Long id);
     *
     *     获取到的是:   [name,id]
     *
     *
     * @return
     */
    public static String[] getMethodParamName(Method method){
        Assert.notNull(method,"传入的方法对象为空");
        method.setAccessible(true);
        DefaultParameterNameDiscoverer discoverer = new DefaultParameterNameDiscoverer();
       return discoverer.getParameterNames(method);
    }


    /**
     * 借助spring 的工具类,注意需要jdk8及其以上
     *      * 获取方法的参数的名称(不是类型),普通类的方法参数,不能获取到接口的方法的参数名称
     *      *
     *      * 例如:    public String test(String name,Long id);
     * @param method
     * @return
     */
    public static String[] getMethodParamNameNoInterface(Method method){
        Assert.notNull(method,"传入的方法对象为空");
        method.setAccessible(true);
        LocalVariableTableParameterNameDiscoverer discoverer = new LocalVariableTableParameterNameDiscoverer();
        return discoverer.getParameterNames(method);
    }


    public static void main(String[] args) throws Exception{


        /***   有实现类的接口**/
        Method test = UserService.class.getMethod("userTest", String.class, Long.class, int.class);
        String[] paramName = getMethodParamName(test);
        log.info("userService有实现类的接口方法名称:{},方法的参数名称:{}",test.getName(), Arrays.toString(paramName));

        /***没有实现类的接口方法参数名称获取***/
        Method adminTest = AdminService.class.getMethod("adminTest", String.class, int.class);
        String[] methodParamName = getMethodParamName(adminTest);
        log.info("userService有实现类的接口方法名称:{},方法的参数名称:{}",adminTest.getName(), Arrays.toString(methodParamName));

        /***获取类的方法参数名称**/

        Method userTest = UserServiceImpl.class.getMethod("userTest", String.class, Long.class, int.class);
        String[] name = getMethodParamName(userTest);
        log.info("userService类的方法:{},方法的参数名称:{}",adminTest.getName(), Arrays.toString(name));

        System.out.println("----------------------下面为测试只能获取类的方法参数名称,获取不到接口的方法的参数名称---------------------------");

        /*****获取接口的方法参数名称******/
        String[] nameNoInterface = getMethodParamNameNoInterface(test);
        log.info("adminService有实现类的接口方法名称:{},方法的参数名称:{}",test.getName(), Arrays.toString(nameNoInterface));

        /***获取类的方法参数名称**/
        String[] noInterface = getMethodParamNameNoInterface(userTest);
        log.info("adminService类的方法:{},方法的参数名称:{}",test.getName(), Arrays.toString(noInterface));

    }

}

 

编写接口和实现类:

UserService

package com.wm.ruanyan1.service;

/**
 * @author 半卷流年
 * @date 2020-6-20 10:19
 */
public interface UserService {

    String userTest(String name,Long id,int count);



}

实现类:

UserServiceImpl

package com.wm.ruanyan1.service.impl;

import com.wm.ruanyan1.service.UserService;

/**
 * @author 半卷流年
 * @date 2020-6-20 10:20
 */
public class UserServiceImpl implements UserService {

    @Override
    public String userTest(String name, Long id, int count) {
        return "success";
    }
}

 

编写一个没有实现类的接口:

AdminService

package com.wm.ruanyan1.service;

/**
 * @author 半卷流年
 * @date 2020-6-20 10:21
 */
public interface AdminService {

    String adminTest(String mobile,int age);
}

 

测试结果:

 

 

 

可以看到成功获取到了方法的参数名称列表,是按照顺序的

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章