通過反射獲取方法的引數名稱(JDK8以上支援)
阿新 • • 發佈:2019-01-01
方法的引數名,在很多時候我們是需要反射得到的。但是在java8之前,程式碼編譯為class檔案後,方法引數的型別是固定的,但引數名稱卻丟失了,這和動態語言嚴重依賴引數名稱形成了鮮明對比。(java是靜態語言,所以入參名稱叫什麼其實無所謂的)。
雖然名稱無所謂,但很多時候,我們需要此名稱來做更好的安排,比如Myabtis的應用。下面介紹兩種方式獲取引數名:
一、通過jdk原生反射機制獲取
import java.lang.reflect.Method; import java.lang.reflect.Parameter; import java.util.ArrayList;import java.util.List; public class ParameterNameUtil { public static void main(String[] args) { List<String> paramterNames = getParameterNameJava8( ParameterNameUtil.class, "getParameterNameJava8"); paramterNames.forEach((x) -> System.out.println(x)); }public static List<String> getParameterNameJava8(Class clazz, String methodName) { List<String> paramterList = new ArrayList<>(); Method[] methods = clazz.getDeclaredMethods(); for (Method method : methods) { if (methodName.equals(method.getName())) {//直接通過method就能拿到所有的引數 Parameter[] params = method.getParameters(); for (Parameter parameter : params) { paramterList.add(parameter.getName()); } } } return paramterList; } }
Java 8開始增加了類Parameter,在class檔案中保留引數名,給反射帶來了極大的便利。
二、通過spring的LocalVariableTableParameterNameDiscoverer獲取
public static void main(String[] args) { List<String> paramterNames = getParamterName(ParameterNameUtil.class, "getParamterName"); paramterNames.forEach((x) -> System.out.println(x)); } public static List<String> getParamterName(Class clazz, String methodName) { LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer(); Method[] methods = clazz.getDeclaredMethods(); for (Method method : methods) { if (methodName.equals(method.getName())) { //獲取到該方法的引數們 String[] params = u.getParameterNames(method); return Arrays.asList(params); } } return null; }
備註:如果不用Class,而是通過spring注入的例項,然後instance.getClass.getDeclaredMethods()則無法得到引數名,除錯時看到方法名稱是通過jdk代理過的,拿不到引數名。
另外,能成功獲取方法引數的名稱需要滿足兩個條件:
- JDK版本必須是1.8及以上
- 編譯時候必須有編譯選項:javac -parameters開啟,預設是關閉的
IDEA配置方法如下: