java1.8获取类和接口函数参数名称

代码如下

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配置编译时参数:

java1.8获取类和接口函数参数名称_第1张图片

方式2:maven插件配置编译时参数

java1.8获取类和接口函数参数名称_第2张图片

编译后查看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."":()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

java1.8获取类和接口函数参数名称_第3张图片

你可能感兴趣的:(函数名称,java8,字节码)