前言
java8新增了一個編譯參數-parameters,可以讓我們在運行期獲取方法參數名稱。
簡單使用
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
public class TestParameter {
public static void main(String[] args) throws Exception {
Method testMethod = TestParameter.class.getDeclaredMethod("test", int.class);
for (Parameter parameter : testMethod.getParameters()) {
System.out.println(parameter.getName());
}
}
private static void test(int num) {
}
}
默認編譯
javac TestParameter.java
運行結果為
arg0
添加編譯參數編譯
javac -parameters TestParameter.java
運行結果為
num
IDEA
IDEA設置編譯參數
maven
maven設置編譯參數,版本3.6.2之前
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<compilerArgs>-parameters</compilerArgs>
</configuration>
</plugin>
版本3.6.2及之后
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<parameters>true</parameters>
</configuration>
</plugin>
Spring框架
SpringBoot項目如果繼承自spring-boot-starter-parent,會默認開啟。
我們也可以查看最終生效的POM文件來確認這一點
看一個SpringMVC中使用到的例子
@GetMapping(value = "/{name}")
public String test(@PathVariable String name);
SpringMVC解析請求參數時,就會使用到這個特性。
主要使用到了DefaultParameterNameDiscoverer,這是一個組合類。
先通過StandardReflectionParameterNameDiscoverer獲取,顧名思義通過反射來獲取參數名稱,如果我們在編譯時沒有添加這個編譯參數,再通過LocalVariableTableParameterNameDiscoverer來獲取,這個涉及到一個 局部變量表 的概念,內部是通過ASM(一個java字節碼操作框架)來實現的。
參考
Java編譯保留方法參數名稱
啟用maven_啟用 parameters 編譯選項簡化 mybatis @Param 注解重復問題
How to compile Spring Boot applications with Java 8 --parameter flag
JAVA局部變量表
