如何保存方法中参数的名称
结论
方法的参数名称可以保存在 MethodParameters 属性中。
代码验证
Java
请将以下代码保存为 A.java ⬇️
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
class A {
int add(int p1, int p2) {
return p1 + p2;
}
public static void main(String[] args) throws NoSuchMethodException {
Method method = A.class.getDeclaredMethod("add", int.class, int.class);
for (Parameter parameter : method.getParameters()) {
System.out.println(parameter.getName());
}
}
}
用如下命令可以编译 A.java 并运行其中的 main(...) 方法 ⬇️
javac A.java
java A
运行结果如下 ⬇️
arg0
arg1
从 java.lang.reflect.Parameter#getName 的 javadoc 可以看到,arg0/arg1 都是合成的名称。
为了保存参数的名称,我们需要在使用 javac 命令时使用 -parameters 选项。
让我们用如下的命令再运行一次 ⬇️
javac -parameters A.java
java A
结果如下
p1
p2
那么参数的名称是如何保存的呢?我们可以用以下的命令来查看 A.class 的内容 ⬇️
javap -v -p A
完整的结果有点长,我只把与 add(int, int) 方法相关的部分展示出来 ⬇️
int add(int, int);
descriptor: (II)I
flags: (0x0000)
Code:
stack=2, locals=3, args_size=3
0: iload_1
1: iload_2
2: iadd
3: ireturn
LineNumberTable:
line 6: 0
MethodParameters:
Name Flags
p1
p2
看来参数名 (就这个例子而言,是 p1/p2) 保存在了 MethodParameters 属性里。
Java Virtual Machine Specification 4.7.24. The MethodParameters Attribute 中有关于这个属性的详细描述。
Scala
在使用 Scala 时,我们也可以保存和读取参数的名称。让我们用代码来验证吧 (请将以下代码保存为 B.scala)
class B {
def add(p1: Int, p2: Int): Int = {
p1 + p2
}
}
下方的命令可以编译 B.scala
scalac B.scala
我们用下方的命令可以看到对应字节码的详细内容
javap -v -p B
完整的结果有点长,我只把和 add 方法相关的部分粘贴过来
public int add(int, int);
descriptor: (II)I
flags: (0x0001) ACC_PUBLIC
Code:
stack=2, locals=3, args_size=3
0: iload_1
1: iload_2
2: iadd
3: ireturn
LineNumberTable:
line 3: 0
LocalVariableTable:
Start Length Slot Name Signature
0 4 0 this LB;
0 4 1 p1 I
0 4 2 p2 I
MethodParameters:
Name Flags
p1 final
p2 final
看来 Scala 也会使用 MethodParameters 属性来保存参数的名称。