java8反射获取方法的参数名称 类和接口
1.简要说明
-
演示
springboot版本为2.0.3.RELEASE -
为啥要分
java类和java接口两种进行参数获取的演示java类编译成class文件后,方法签名和参数会保存在字节码文件中,通过一些字节码的解析框架可以获取方法的参数名称java接口编译成class文件后,默认不会保存方法的参数签名,jdk这么设计,因为接口的参数名称一般没有意义,但是现在的技术发展导致一些框架需要用到接口的参数名称- spring openFeign 中使用接口进行编程
- mybatis 中的 Mapper 文件接口
- 其他一些动态代理接口的编程方式
-
在Java8之后,反射包
package java.lang.reflect;新加入了Parameter类,可以解决这类问题
指导文章
https://docs.oracle.com/javase/tutorial/reflect/member/methodparameterreflection.html
Java 8 + 增加 javac -parameters 参数
大前提:必须是 Java 8
package java.lang.reflect;
...
/**
* Information about method parameters.
*
* A {@code Parameter} provides information about method parameters,
* including its name and modifiers. It also provides an alternate
* means of obtaining attributes for the parameter.
*
* @since 1.8
*/
public final class Parameter implements AnnotatedElement {
private final String name;
private final int modifiers;
private final Executable executable;
private final int index;
...
}
2.java类获取方法参数名称
测试代码
- 使用
spring中的ParameterNameDiscoverer类获取方法的参数 - 使用传统的
java反射获取参数名称
/**
* 测试反射获取类方法参数
*/
public class ParameterDemo {
public String say(String message){
return "hello world:"+message;
}
public static void main(String[] args) {
Method method = ReflectionUtils.findMethod(ParameterDemo.class,"say",String.class);
ParameterNameDiscoverer discoverer = new DefaultParameterNameDiscoverer();
String[] parameterNames = discoverer.getParameterNames(method);
Stream.of(discoverer.getParameterNames(method)).forEach(System.out::println);
methodTest();
}
public static void methodTest() {
Method method = ReflectionUtils.findMethod(ParameterDemo.class,"say",String.class);
Parameter parameter = method.getParameters()[0];
System.out.println(parameter.getName());
}
}
执行结果
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Xsjeny78-1570846606132)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1570845320634.png)]](https://i-blog.csdnimg.cn/blog_migrate/e3c8af8fd10919533c607c279d778fe8.png)
-
spring通过字节码解析技术获取到了方法的参数名称 -
传统的反射方法无法获取参数名称
解决方法
增加 javac -parameters 参数
通过maven的方式
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<debug>true</debug>
<debuglevel>lines,vars,source</debuglevel>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
关键代码
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
先 clean 再 compiler
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5bJrJBto-1570846606132)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1570846353164.png)]](https://i-blog.csdnimg.cn/blog_migrate/e14d251385959a1d5bc19907520f9766.png)
执行结果
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o9LAxfsl-1570846606133)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1570846400305.png)]](https://i-blog.csdnimg.cn/blog_migrate/90231249229962105584ffd3a5137cdc.png)
3.接口获取方法参数名称
测试代码
/**
* 测试反射获取接口方法参数
*/
public interface ParameterInterfaceDemo {
String say(String message);
public static void main(String[] args) {
Method method = ReflectionUtils.findMethod(ParameterInterfaceDemo.class,"say",String.class);
ParameterNameDiscoverer discoverer = new DefaultParameterNameDiscoverer();
String[] parameterNames = discoverer.getParameterNames(method);
try {
Stream.of(discoverer.getParameterNames(method)).forEach(System.out::println);
}catch (Exception e){
e.printStackTrace();
}
methodTest();
}
public static void methodTest() {
Method method = ReflectionUtils.findMethod(ParameterInterfaceDemo.class,"say",String.class);
Parameter parameter = method.getParameters()[0];
System.out.println(parameter.getName());
}
}
执行结果
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iXSMAlUj-1570846606133)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1570845289586.png)]](https://i-blog.csdnimg.cn/blog_migrate/ecc90cee07a3beb4df2a144362b26952.png)
在接口中,不管是spring通过字节码技术还是传统的反射方法都无法获取
解决方法
增加 javac -parameters 参数
通过maven的方式
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<debug>true</debug>
<debuglevel>lines,vars,source</debuglevel>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
关键代码
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
先 clean 再 compiler
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LS56BiId-1570846606134)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1570846353164.png)]](https://i-blog.csdnimg.cn/blog_migrate/c422f1537f5b61e447617aad7994b3c1.png)
执行结果
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RskZ22b1-1570846606134)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1570846400305.png)]](https://i-blog.csdnimg.cn/blog_migrate/8c3400cc0dfb1f8883462a86ec533868.png)
感谢
mercyblitz - 小马哥的讲解 博客地址 (https://mercyblitz.github.io)
Java8反射获取方法参数名
本文介绍如何在Java8中使用反射获取类和接口方法的参数名称,包括使用spring的ParameterNameDiscoverer和Java反射Parameter类。演示了在默认情况下无法获取参数名的问题,并提供了解决方案,即通过增加javac-parameters参数来实现。
758





