java 反射 参数名_JAVA 8 反射获取参数名
前言
在JDK8之前javac編譯是不會把構(gòu)造器和方法的參數(shù)名編譯進(jìn)class中,如果需要獲取參數(shù)名,可以在方法上加上注解,反射獲取注解的值從而獲取參數(shù)名,比如Jackson的@JsonCreator和@JsonProperty 。而JDK8新增了這一個功能,可以直接調(diào)用java.lang.reflect.Parameter.getName()獲取到,前提是javac需要添加-parameters這個參數(shù)。通常來說不建議這樣做,因為這會增大.class和在JVM中會占用更多的內(nèi)存。
正文
代碼
直接上代碼。
用來打印類信息
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import static java.lang.System.out;
public class MethodParameterSpy {
private static final String fmt = "%24s: %s%n";
public static void printClassConstructors(Class c) {
Constructor[] allConstructors = c.getConstructors();
out.format(fmt, "Number of constructors", allConstructors.length);
for (Constructor currentConstructor : allConstructors) {
printConstructor(currentConstructor);
}
Constructor[] allDeclConst = c.getDeclaredConstructors();
out.format(fmt, "Number of declared constructors",
allDeclConst.length);
for (Constructor currentDeclConst : allDeclConst) {
printConstructor(currentDeclConst);
}
}
public static void printClassMethods(Class c) {
Method[] allMethods = c.getDeclaredMethods();
out.format(fmt, "Number of methods", allMethods.length);
for (Method m : allMethods) {
printMethod(m);
}
}
public static void printConstructor(Constructor c) {
out.format("%s%n", c.toGenericString());
Parameter[] params = c.getParameters();
out.format(fmt, "Number of parameters", params.length);
for (int i = 0; i < params.length; i++) {
printParameter(params[i]);
}
}
public static void printMethod(Method m) {
out.format("%s%n", m.toGenericString());
out.format(fmt, "Return type", m.getReturnType());
out.format(fmt, "Generic return type", m.getGenericReturnType());
Parameter[] params = m.getParameters();
for (int i = 0; i < params.length; i++) {
printParameter(params[i]);
}
}
public static void printParameter(Parameter p) {
out.format(fmt, "Parameter class", p.getType());
out.format(fmt, "Parameter name", p.getName());
out.format(fmt, "Modifiers", p.getModifiers());
out.format(fmt, "Is implicit?", p.isImplicit());
out.format(fmt, "Is name present?", p.isNamePresent());
out.format(fmt, "Is synthetic?", p.isSynthetic());
}
public static void main(String... args) {
printClassConstructors(ExampleMethods.class);
printClassMethods(ExampleMethods.class);
}
}
包含各種類型方法的類
import java.util.*;
public class ExampleMethods {
public boolean simpleMethod(String stringParam, int intParam) {
System.out.println("String: " + stringParam + ", integer: " + intParam);
return true;
}
public int varArgsMethod(String... manyStrings) {
return manyStrings.length;
}
public boolean methodWithList(List listParam) {
return listParam.isEmpty();
}
public void genericMethod(T[] a, Collection c) {
System.out.println("Length of array: " + a.length);
System.out.println("Size of collection: " + c.size());
}
}
不帶-parameters
不帶-parameters運行結(jié)果:
Number of constructors: 1
public ExampleMethods()
Number of parameters: 0
Number of declared constructors: 1
# 構(gòu)造器
public ExampleMethods()
Number of parameters: 0
Number of methods: 4
# 方法一
public boolean ExampleMethods.simpleMethod(java.lang.String,int)
Return type: boolean
Generic return type: boolean
Parameter class: class java.lang.String
Parameter name: arg0
Modifiers: 0
Is implicit?: false
Is name present?: false
Is synthetic?: false
Parameter class: int
Parameter name: arg1
Modifiers: 0
Is implicit?: false
Is name present?: false
Is synthetic?: false
# 方法二
public boolean ExampleMethods.methodWithList(java.util.List)
Return type: boolean
Generic return type: boolean
Parameter class: interface java.util.List
Parameter name: arg0
Modifiers: 0
Is implicit?: false
Is name present?: false
Is synthetic?: false
# 方法三
public void ExampleMethods.genericMethod(T[],java.util.Collection)
Return type: void
Generic return type: void
Parameter class: class [Ljava.lang.Object;
Parameter name: arg0
Modifiers: 0
Is implicit?: false
Is name present?: false
Is synthetic?: false
Parameter class: interface java.util.Collection
Parameter name: arg1
Modifiers: 0
Is implicit?: false
Is name present?: false
Is synthetic?: false
# 方法四
public int ExampleMethods.varArgsMethod(java.lang.String...)
Return type: int
Generic return type: int
Parameter class: class [Ljava.lang.String;
Parameter name: arg0
Modifiers: 0
Is implicit?: false
Is name present?: false
Is synthetic?: false
可以看出Parameter name全都是arg0~argN,因為參數(shù)名在編譯期已經(jīng)丟失了。Is name present為false。
帶-parameters
maven在pom.xml中添加
org.apache.maven.plugins
maven-compiler-plugin
8
8
-parameters
命令行在javac 后面加 -parameters
運行結(jié)果
Number of constructors: 1
public ExampleMethods()
Number of parameters: 0
Number of declared constructors: 1
# 構(gòu)造器
public ExampleMethods()
Number of parameters: 0
Number of methods: 4
# 方法一
public boolean ExampleMethods.methodWithList(java.util.List)
Return type: boolean
Generic return type: boolean
Parameter class: interface java.util.List
Parameter name: listParam
Modifiers: 0
Is implicit?: false
Is name present?: true
Is synthetic?: false
# 方法二
public int ExampleMethods.varArgsMethod(java.lang.String...)
Return type: int
Generic return type: int
Parameter class: class [Ljava.lang.String;
Parameter name: manyStrings
Modifiers: 0
Is implicit?: false
Is name present?: true
Is synthetic?: false
# 方法三
public void ExampleMethods.genericMethod(T[],java.util.Collection)
Return type: void
Generic return type: void
Parameter class: class [Ljava.lang.Object;
Parameter name: a
Modifiers: 0
Is implicit?: false
Is name present?: true
Is synthetic?: false
Parameter class: interface java.util.Collection
Parameter name: c
Modifiers: 0
Is implicit?: false
Is name present?: true
Is synthetic?: false
# 方法四
public boolean ExampleMethods.simpleMethod(java.lang.String,int)
Return type: boolean
Generic return type: boolean
Parameter class: class java.lang.String
Parameter name: stringParam
Modifiers: 0
Is implicit?: false
Is name present?: true
Is synthetic?: false
Parameter class: int
Parameter name: intParam
Modifiers: 0
Is implicit?: false
Is name present?: true
Is synthetic?: false
這樣就把參數(shù)名給打印出來了,Is name present為true。
留個問題
出于好奇,以十六進(jìn)制打開ExampleMethods的class文件,maven項目在idea中build出來的class不管有沒有帶-parameters都會把參數(shù)名編譯進(jìn)去,但是多了MethodParameters這幾個字眼。如下圖:
然后嘗試直接用javac -parameters編譯,打開后
很明顯是沒有把參數(shù)名編譯進(jìn)去的。
好像找不到idea執(zhí)行build的時候執(zhí)行了什么,所有我猜測控制java.lang.reflect.Parameter.getName()返回是否真實的參數(shù)名就是在于MethodParameters這詞,在jvm加載class時識別是否有MethodParameters,而決定是否加載參數(shù)名。
這僅是猜測,望大家相告是其真正的原理。
文中也可能存在錯誤,也望大家指出。
代碼來源
上述代碼全部來自#參考資料中的Obtaining Names of Method Parameters
參考資料
與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的java 反射 参数名_JAVA 8 反射获取参数名的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: web开发常用工具介绍
- 下一篇: java post 提交数据_使用Pos