Java获取代码中方法参数名信息的方法

前言

大家都知道随着java8的使用,在相应的方法签名中增加了新的对象Parameter,用于表示特定的参数信息,通过它的getName可以获取相应的参数名.即像在代码中编写的,如命名为username,那么在前台进行传参时,即不需要再编写如@Parameter("username")类的注解,而直接就能进行按名映射.

如下的代码参考所示:

public class T {
 private interface T2 {
  void method(String username, String password);
 }

 public static void main(String[] args) throws Exception {
  System.out.println(T.class.getMethod("main", String[].class).getParameters()[0].getName());
  System.out.println(T2.class.getMethod("method", String.class, String.class).getParameters()[0].getName());
  System.out.println(T2.class.getMethod("method", String.class, String.class).getParameters()[1].getName());
 }
}

按java8之前,也可以通过一些手段拿到参数名信息,只不过方式不同而已.如通过spring mvc中的ParameterMethodNameResolver在之前的版本中也可以正常工作.不过需要特别的编译而已.这里面起作用的即是 LocalVariableTableMethodParameters,中文编译为本地变量表和方法参数表.

LocalVariableTable 本地变量表

按jvm规范所述,本地变量表存在于Code属性中,而Code属性即又是methodInfo的一个属性.可以理解为,当一个方法有方法体时,就会出现相应的Code属性,而且在code属性中,除具体的执行代码外,还会有其它的信息.如LineNumberTable(用于描述每一行代码所在的位置).

本地变量表属于在方法中调试信息的一部分,因此默认情况下这些信息是不会生成在class文件当中的.需要开启 -g 或 -g:vars 开关.还好,对于ide或者是maven编译来说,这些开关都是默认开启的.在ide中,可以通过设置(generate debugging info 针对idea)来控制(默认打勾).在maven中,通过通过插件 maven-compiler-plugin 中的debug或debugLevel来控制是否输出(默认值是true).

本地变量表在javap之后,如下所示:

//非静态方法
  LocalVariableTable:
  Start Length Slot Name Signature
   0  1  0 this LT;
   0  1  1 count J
   0  1  3 name Ljava/lang/String;

//静态方法
  LocalVariableTable:
  Start Length Slot Name Signature
   0  101  0 args [Ljava/lang/String;

本地变量表不仅保存了参数信息,还保存在在整个方法体中可能会使用的临时变量,如声明的int i等.并且如上所示,表示方法和非静态方法,在第一位还有this变量的区别.因此,可以通过读取参数个数(method.getParameterCount),然后再根据方法签名,读取本地变量表中指定个数的参数信息即可.

需要注意的是,在上图中,如果参数为long或double,其slot占位为2个,在通过slot来获取参数信息时,需要考虑参数的类型信息.

接口方法由于没有code属性,因此也没有本地变量表,拿到一个接口的方法定义,通过本地变量表是不能获取到相应的参数名的

MethodParameters 方法参数表

方法参数表是在1.8之后引入的,因此只是使用jdk8编译生成的class文件才有此信息. 与本地变量表不同,它是属于MethodInfo属性的,即它是与Code属性同一级别的.不管是接口方法还是普通的方法,都是有此属性的.因此,即使是接口方法,也可以获取相应的参数信息.

默认情况下,class中是没有此信息的.需要使用特殊的编译参数 -parameters 才能生成,并且在ide和maven中,也默认不会生成此信息.在idea中,需要在java additional line parameters中增加此编译参数.在maven中,也需要在maven-compiler-plugin的compilerArgs参数中增加此参数才行.

方法参数表在javap之后,表现为如下形式:

//非静态方法
 MethodParameters:
  Name       Flags
  count
  name

//静态方法
 MethodParameters:
  Name       Flags
  args

可以看出,无论是否静态,在参数表中,只会出现用于描述参数的信息.后面的Flags参数用于一些特殊的场景,比如final参数用于方法改写等.

可使用的一些工具

除使用原生的api,以及spring工具包,还有其它一些工具都可以拿到参数名信息.在spring体系中,用于描述参数名的接口为 ParameterNameDiscoverer.通过它可以获取相应的参数名信息. 除此之外, com.thoughtworks.paranamer:paranamer 这一工具包中的Paranamer 也可以同样进行相应信息的处理. 不过对于jdk8的methodParameters支持度还不是很高,使用者可以通过扩展它来达到自己的目的.

总结

以上就是为大家总结的Java获取代码中方法参数名信息的方法,希望对大家学习或使用Java带来一定的帮助,如果有疑问大家可以留言交流。

(0)

相关推荐

  • java中如何获取相关参数

    此文通过一段代码来展示java获取相关参数的方法分享给大家: public static void main(String[] args) { Properties props=System.getProperties(); //系统属性 System.out.println("Java的运行环境版本:"+props.getProperty("java.version")); System.out.println("Java的运行环境供应商:"+

  • 在java代码中获取JVM参数的方法

    实例如下: MemoryMXBean memorymbean = ManagementFactory.getMemoryMXBean(); MemoryUsage usage = memorymbean.getHeapMemoryUsage(); System.out.println("INIT HEAP: " + usage.getInit()); System.out.println("MAX HEAP: " + usage.getMax()); System.

  • Java获取代码中方法参数名信息的方法

    前言 大家都知道随着java8的使用,在相应的方法签名中增加了新的对象Parameter,用于表示特定的参数信息,通过它的getName可以获取相应的参数名.即像在代码中编写的,如命名为username,那么在前台进行传参时,即不需要再编写如@Parameter("username")类的注解,而直接就能进行按名映射. 如下的代码参考所示: public class T { private interface T2 { void method(String username, Stri

  • Android开发获取系统中已安装程序信息的方法

    本文实例讲述了Android开发获取系统中已安装程序信息的方法.分享给大家供大家参考,具体如下: public class AppInfoParser { private static String tag = "AppInfoParser"; public static List<AppInfo> getAppInfos(Context context){ //首先获取到包的管理者 PackageManager packageManager = context.getPa

  • java向多线程中传递参数的三种方法详细介绍

    在传统的同步开发模式下,当我们调用一个函数时,通过这个函数的参数将数据传入,并通过这个函数的返回值来返回最终的计算结果.但在多线程的异步开发模式下,数据的传递和返回和同步开发模式有很大的区别.由于线程的运行和结束是不可预料的,因此,在传递和返回数据时就无法象函数一样通过函数参数和return语句来返回数据.本文就以上原因介绍了几种用于向线程传递数据的方法,在下一篇文章中将介绍从线程中返回数据的方法. 欲先取之,必先予之.一般在使用线程时都需要有一些初始化数据,然后线程利用这些数据进行加工处理,并

  • java 获取request中的请求参数代码详解

    1.get 和 post请求方式 (1)request.getParameterNames(); 获取所有参数key后.遍历request.getParameter(key)获取value (2)request.getParameterMap() .直接包含参数key和value值,简单方便 Map<String, String[]>maps = request.getParameterMap(); for (Map.Entry<String, String[]> entry :

  • 聊聊在获取方法参数名方面,Spring真的就比Mybatis强?

    目录 前言 一.Spring是如何获取方法参数名称的? Spring获取参数名称的两种方式 二.Mybatis为什么没有向Spring学习? Mybatis要获取的是接口方法的参数名称 三.总结 四.深入拓展 1.从字节码说起 2.看看普通类在不同参数编译下的.class字节码里面都有什么 3.看看接口在不同参数编译下的.class字节码里面都有什么 五.结束 前言 在使用 Spring MVC 写Controller的时候,即使不使用注解,只要参数名和请求参数的key对应上了,就能自动完成数值

  • Java获取彩色图像中的主色彩的实例代码

    本文讲述了Java获取彩色图像中的主色彩的实例代码.分享给大家供大家参考,具体如下: 一:基本思路 对于一张RGB色彩空间的彩色图像,很多时间我们想通过程序获得该图像有几种主要的色彩,但是对一般图像来说,在色彩交界处都是通过像素混合来实现自然过渡,所以直接扫描图像的像素值,得到的不同颜色值可能多达上百中,而实际上图像可能只有3-4种的主要色彩,如何去掉那些混合颜色,准确提取出来这3-4中的主色彩,根据一般图像的特征,图像在不同色彩的边界处混合不同的颜色值,此可以视为图像的边缘特性之一,因此可以根

  • java 获取对象中为null的字段实例代码

    下面一段简单的代码给大家分享java 获取对象中为null的字段,具体代码如下所述: private static String[] getNullPropertyNames(Object source) { final BeanWrapper src = new BeanWrapperImpl(source); java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors(); Set<String> emptyNames

  • 浅析JS获取url中的参数实例代码

    js获取url中的参数代码如下所示,代码简单易懂,附有注释,写的不好还请见谅! function UrlSearch() { var name, value; var str = location.href; //取得整个地址栏 var num = str.indexOf("?") str = str.substr(num + 1); //取得所有参数 stringvar.substr(start [, length ] var arr = str.split("&&

  • 使用JavaScript获取URL中的参数(两种方法)

    本文给大家分享两种方法使用js获取url中的参数,其中方法二是使用的正则表达式方法,大家可以根据需要选择比较好的方法,废话不多说了,直接看详细介绍吧. 方法一: //取url参数 var type = request("type") function request() { var query = location.search; var paras = arguments[0]; if (arguments.length == 2) { query = arguments[1]; }

  • java 获取冒号后面的参数(正则)实现代码

    我就废话不多说了,大家还是直接看代码吧~ String regEx=":[\\S]+"; String sql=" select * from a where id=:id and name=:zhangsan "; Pattern p = Pattern.compile(regEx); Matcher m = p.matcher(sql); while(m.find()) { System.out.println(m.group()); } 补充知识:Java-正

随机推荐