java1.8獲取類和介面函式引數名稱
阿新 • • 發佈:2019-02-19
程式碼如下
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