java 获取方法名称_(Java8) 如何获取方法中的参数名称

参考材料

原理简述

java8 对应的 javac 命令支持 -parameters 选项。如果编译时启用该选项,构造函数和普通方法的参数名称会被保存到编译所得的 class 文件中。

参考材料[2] 中的原文如下

Stores formal parameter names of constructors and methods in the generated class file so that the method java.lang.reflect.Executable.getParameters from the Reflection API can retrieve them.

我们通过 jdk 提供的反射相关 api 就可以访问到这些参数名称了(由于相关信息已经保存在 class 文件里了,直接用 javap 分析 class 文件也能看到这些参数名)

实战

构造函数(constructors)和普通方法(methods)我各写一个例子来演示效果。

构造函数

代码

import java.lang.reflect.Constructor;

import java.lang.reflect.Parameter;

public class Show {

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

// 找到那个构造函数

Constructor constructor = Show.class.getConstructor(int.class, Object.class);

for (Parameter parameter : constructor.getParameters()) {

System.out.println("参数名为: " + parameter.getName());

}

}

/**

* 由于不关心构造函数里的逻辑, 这个构造函数内就没有写任何代码

* 两个参数都相当于占位符

*

* @param firstPlaceHolderWithALongName 就是个展示符, 名字很长, 容易被看到

* @param secondPlaceHolder 也是一个占位符

*/

public Show(int firstPlaceHolderWithALongName, Object secondPlaceHolder) {

}

}

将上述代码保存为 Show.java。

编译

用如下命令对 Show.java 进行编译(注意:要加上 -parameters 选项才能看到效果)

javac -parameters Show.java

运行

用如下命令运行得到的 class 文件(注意不要加 .class 后缀名)

java -cp . Show

确认结果

结果如下

8b933ca39c0e

查看构造函数中各个参数的名称

如果直接用 javap 分析得到 Show.class 的话,也可以看到对应的参数名。

用到的命令如下

javap -cp . -v -p Show

完整的结果较长,class 文件的结构是一个比较大的话题(且本文作者水平有限,也只知道个大概),这里就不多说了。相关结果截图如下

8b933ca39c0e

在 MethodParameters 属性部分可以看到参数名称

另外,如果编译时没有写 -parameters 选项的话,编译时的命令就会是

# 这样是看不到参数名称的

javac Show.java

仍旧使用如下命令运行得到的 class 文件

java -cp . Show

这样就只能看到 arg0 arg1 这样的变量名了。运行效果示意图如下

8b933ca39c0e

只能看到自动生成的变量名

我在 java.lang.reflect.Parameter 中看到了如下的一段话,可以解释为何现在看到的变量名是 arg0 和 arg1

8b933ca39c0e

变量名为何是 arg0 arg1

看一下 getName() 的源码(如下图),会发现,当 name 为 null 或 "" 时,返回值就会是 argN 这种样子的。

8b933ca39c0e

getName() 方法的源码

javap -cp . -v -p Show

此时如果使用上述命令分析 class 文件,会发现之前看到的 MethodParameters 属性也不见了

8b933ca39c0e

MethodParameters 属性消失

普通方法

代码

import java.lang.reflect.Method;

import java.lang.reflect.Parameter;

public class Show {

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

// 找到那个函数

Method method = Show.class.getDeclaredMethod("dummy", int.class, Object.class);

for (Parameter parameter : method.getParameters()) {

System.out.println("参数名为: " + parameter.getName());

}

}

/**

* 由于不关心这个函数里的逻辑, 此函数内就没有写任何代码

* 两个参数都相当于占位符

*

* @param firstPlaceHolderWithALongName 就是个展示符, 名字很长, 容易被看到

* @param secondPlaceHolder 也是一个占位符

*/

private void dummy(int firstPlaceHolderWithALongName, Object secondPlaceHolder) {

}

}

编译

用如下命令对 Show.java 进行编译

javac -parameters Show.java

运行

用如下命令运行得到的 class 文件

java -cp . Show

确认结果

结果如下

8b933ca39c0e

查看普通方法中各个参数的名称

如果直接用 javap 分析得到 Show.class 的话,也可以看到对应的参数名。

用到的命令如下

javap -cp . -v -p Show

相关结果截图如下

8b933ca39c0e

在 MethodParameters 属性部分可以看到参数名称

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值