Java——通过反射获取函数参数名称

本文介绍了三种在Java中获取方法参数名称的方法:使用javassist、Spring的LocalVariableTableParameterNameDiscoverer及Java8新增的Parameter类。重点讲解了如何在Java8中利用Parameter类直接从方法对象获取参数名,并提供了IDEA配置参数名保留的方法。

通过javassit获取

参见 http://blog.csdn.net/viviju1989/article/details/8529453 这篇文章的方法一,实现比较麻烦,就不说了。

通过spring的LocalVariableTableParameterNameDiscoverer

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代理过的,拿不到参数名。

通过Java8的Parameter类

在Java 8之前的版本,代码编译为class文件后,方法参数的类型是固定的,但参数名称却丢失了,这和动态语言严重依赖参数名称形成了鲜明对比。现在,Java 8开始在class文件中保留参数名,给反射带来了极大的便利。jdk8增加了类Parameter

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())) {
                Parameter[] params = method.getParameters();
                for(Parameter parameter : params){
                    paramterList.add(parameter.getName());
                }

            }
        }

        return paramterList;
    }

如果编译级别低于1.8,得到的参数名称是无意义的arg0、arg1……
遗憾的是,保留参数名这一选项由编译开关javac -parameters打开,默认是关闭的。
注意此功能必须把代码编译成1.8版本的class才行。
idea设置保留参数名:

在 preferences-》Java Compiler->设置模块字节码版本1.8,Javac Options中的 Additional command line parameters: -parameters

参考资料

在Java 8中获取参数名称

### 获取Java方法参数名称Java中,默认情况下编译后的字节码不会保留方法参数名称信息。然而,通过启用特定编译器选项并利用反射API中的`Parameter`类,可以实现这一功能。 为了使程序能够访问方法参数,在编译时需加上`-parameters`标志[^1]。一旦启用了此标记,就可以借助于`java.lang.reflect.Method`对象来获取这些字: ```java import java.lang.reflect.Parameter; import java.util.Arrays; public class GetParamNames { public void exampleMethod(String paramOne, int paramTwo) {} public static void main(String[] args) throws Exception { var method = GetParamNames.class.getMethod("exampleMethod", String.class, int.class); Parameter[] params = method.getParameters(); Arrays.stream(params).forEach(param -> System.out.println(param.getName())); } } ``` 上述代码展示了如何定义一个简单的方法,并通过反射机制打印其参数字。需要注意的是,只有当项目是以支持该特性的JDK版本编译,并且确实指定了`-parameters`选项的情况下才会有效工作。 对于较新的Java版本(8及以上),如果开发者希望更方便地处理函数式接口以及简化某些场景下的Lambda表达式的书写,则可以通过引入方法引用的方式达到目的[^3]。不过这与直接获取运行期可见的方法无关。 尽管如此,了解怎样取得实际传递给某个调用链末端的具体实参列表可能更为实用——比如用于日志记录或调试工具开发等方面;而这一点通常涉及到AOP(面向切面编程)技术或是代理模式的应用,超出了单纯依靠标准库所能完成的功能范围之外。 #### 注意事项 - 编译阶段必须加入`-parameters`开关才能让参数被保存下来供后续查询。 - 此特性适用于Java SE 8及其之后发布的版本。 - 对性能敏感的应用应当谨慎评估因频繁使用反射所带来的开销影响。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值