代码如下
package js.oop.parameter;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Arrays;
/**
* java 1.8
* 编译器时加上-parameters
*/
public abstract class ParameterName {
public void fun(String name1,int age1) {
System.out.println("name:" + name1 + ",age:" + String.valueOf(age1));
}
public abstract void test(String msg,int age);
/**
* 切换编译环境 java1.8
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
Method method = ParameterName.class.getMethod("fun",String.class,int.class);
//@since 1.8
Parameter[] parameters= method.getParameters();
Arrays.stream(parameters).forEach(parameter -> {
System.out.println(parameter.getName());
});
method = ParameterName.class.getMethod("test",String.class,int.class);
parameters= method.getParameters();
Arrays.stream(parameters).forEach(parameter -> {
System.out.println(parameter.getName());
});
}
}
默认情况下:获取的结果是 arg0 和 arg1 ,为什么呢?查看 parameter.getName() 的源代码如下:
public String getName() {
// Note: empty strings as paramete names are now outlawed.
// The .equals("") is for compatibility with current JVM
// behavior. It may be removed at some point.
if(name == null || name.equals(""))
return "arg" + index;
else
return name;
}
那么怎么才能通过代码获取参数名称呢?
编译器时加上-parameters参数
方式1:idea配置编译时参数:
方式2:maven插件配置编译时参数
编译后查看class字节码文件
javap -v ParameterName.class >> 123.txt
发现有不一样的地方.class文件中额外存储参数的元信息 MethodParameters
public void fun(java.lang.String, int);
descriptor: (Ljava/lang/String;I)V
flags: ACC_PUBLIC
Code:
stack=3, locals=3, args_size=3
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: new #3 // class java/lang/StringBuilder
6: dup
7: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V
10: ldc #5 // String name:
12: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
15: aload_1
16: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
19: ldc #7 // String ,age:
21: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
24: iload_2
25: invokestatic #8 // Method java/lang/String.valueOf:(I)Ljava/lang/String;
28: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
31: invokevirtual #9 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
34: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
37: return
LineNumberTable:
line 14: 0
line 15: 37
LocalVariableTable:
Start Length Slot Name Signature
0 38 0 this Ljs/oop/parameter/ParameterName;
0 38 1 name1 Ljava/lang/String;
0 38 2 age1 I
MethodParameters:
Name Flags
name1
age1
public abstract void test(java.lang.String, int);
descriptor: (Ljava/lang/String;I)V
flags: ACC_PUBLIC, ACC_ABSTRACT
MethodParameters:
Name Flags
msg
age