默认情况下,我们是无法获取方法中参数的名称,通过反射机制也只能过去参数的顺序以及一些表意名:arg0、arg1等等;当我们面对,比如文档化服务接口的详细信息时,就会比较麻烦。因为源文件在编译时,不会将参数名称等相关meta信息记入class文件;JDK 8之后,我们可以通过在编译时指定“-parameters”选项,来实现将方法的参数名记入class文件,并在运行时通过反射机制获取相关信息。
如果你的项目为maven构建,可以增加如下配置:
<plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>utf8</encoding> <compilerArgs> <arg>-parameters</arg> </compilerArgs> </configuration> </plugin>
普通JAVA与反射机制:
public class Test { public static void main(String[] args) throws Exception{ Class clazz = Class.forName("com.test.MethodParameterTest"); Method[] methods = clazz.getMethods(); Constructor[] constructors = clazz.getConstructors(); for (Constructor constructor : constructors) { System.out.println("+++" + constructor.getName()); Parameter[] parameters = constructor.getParameters(); for (Parameter parameter : parameters) { printParameter(parameter); } } System.out.println("------------------"); for (Method method : methods) { System.out.println(method.getName()); Parameter[] parameters = method.getParameters(); for (Parameter parameter : parameters) { printParameter(parameter); } } } private static void printParameter(Parameter parameter) { //参数名 System.out.println("\t\t" + parameter.getName()); //是否在源码中隐式声明的参数名 System.out.println("\t\t\t implicit:" + parameter.isImplicit()); //类文件中,是否存在参数名 System.out.println("\t\t\t namePresent:" + parameter.isNamePresent()); //是否为虚构参数 System.out.println("\t\t\t synthetic:" + parameter.isSynthetic()); System.out.println("\t\t\t VarArgs:" + parameter.isVarArgs()); } }
Spring环境下:
public class SpringTest { private static final ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer(); public static void main(String[] args) throws Exception{ Class clazz = Class.forName("com.test.MethodParameterTest"); Method[] methods = clazz.getMethods(); for (Method method : methods) { System.out.println(method.getName()); //JDK 1.8 + is better. String[] parameterNames = parameterNameDiscoverer.getParameterNames(method); if (parameterNames == null) { continue; } for (String pn : parameterNames) { System.out.println("\t\t" + pn); } } } }
1、isImplicit(): 参数是否为“隐式”声明在源文件中,比如内部类,默认构造函数(无参)其实在编译成class时将会把包含它的主类引用作为首个参数,此参数即为隐式声明;如果为true,即表示有JDK编译器隐式生成在class文件中的方法参数,而source文件中并不可见。常规的普通的方法,此值为false。
2、isNamePresent:此参数在class文件中是否有此参数名;受制于在编译时是否指定了“-parameter”,对于指定此参数的编译文件,通常为true;对于JDK 内部类、默认编译的类,通常为false;此时你会发现,它们的参数名通常为表意名称:arg0、arg1等等,此时为false。
3、isSynthetic():是否为“虚构”参数,如果为true,表示既不是“显式”声明、也不是隐式声明在源文件中的参数,比如enum类的“values()”、“valueOf(String)”这是编译器“虚构”的系统方法。
相关推荐
java 反射 调用私有方法(有参数私有方法)获取私有属性值
java 通过反射获取类上注解,方法上注解,注解里的值及方法参数,项目为maven项目。导入时记得选择maven项目
java反射,获取所有属性、方法以及List集合类
Java反射 调用空参方法 调用Object类型参数的方法 调用基本类型参数的方法 调用基本类型数组参数的方法 调用String数组参数的方法 调用Object数组参数的方法 调用私有方法
反射,获取所有属性、方法以及List集合类
本文档是关于java的反射的组件Method的描述
在java中,可以通过反射获取到类、字段、方法签名等相关的信息,像方法名、返回值类型、参数类型、泛型类型参数等,但是不能够获取方法的参数名。在实际开发场景中,有时需要根据方法的参数名做一些操作,那么该如何...
利用java反射原理调用方法时,常先需要传入方法参数数组才能取得方法。该方法参数数组采用动态取得的方式比较合适
利用反射技术,根据类的完全限定名获得该类的实例对象。包括无参数或带参数的实例化。感兴趣的可以看看!
该篇文章主要介绍当我们碰到参数或者返回值是一个对象时,如何通过frida反射调用该对象的方法(methods)与获取该对象的字段(fields)。感兴趣的朋友可以下载下来看看,了解了解
生成额外的信息(运行时非必须信息)会消耗内存并且有可能公布敏感信息(某些方法参数比如password,JDK文档里这么说的),并且确实很多信息javac并不会为
通过反射获取注解的属性值 1、获取类上注解的值 1.1 定义注解类 1.2 定义使用注解的类 1.3 测试类 1.4 测试结果 2、获取属性变量上注解的值 2.1 定义注解类 2.2 定义使用注解的类 2.3 定义测试类 2.4 测试结果 3、...
java反射的工具类,可以获得方法的参数名称
当我们声明了一个泛型的接口或类,或需要一个子类继承至这个泛型类,而我们又希望利用反射获取这些泛型参数信息。这是本文将要介绍的ReflectionUtil是为了解决这类问题的辅助工具类,为java.lang.reflect标准库的...
下面小编就为大家带来一篇java反射遍历实体类属性和类型,并赋值和获取值的简单方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?...在java中,只要给定类的名字,那么就可以通过反射机制来获得类的所有信息。
当遇见java反射机制中的 “获取构造方法” 的错误时,一部分原因是忽略了最容易丢失的参数类型修改。
主要给大家介绍了在Java 8中如何获取参数名称的方法,文中给出了详细的介绍和方法示例,相信对大家的理解和学习具有一定的参考借鉴价值,有需要的朋友可以参考学习,下面来一起看看吧。
DumpMethods.java 使用反射机制来获取类中的方法 getClassName.java 利用反射机制获取类的名字 invokeConstructor.java 利用反射机制调用构造器 invokeMethod.java 利用反射机制调用成员方法 listConstructors....
在反射中,我们需要得到的是构造方法、成员方法、成员变量 得到这些的前提是得到.class文件的类对象 1.Class 1.Class类的静态成员方法,通过完整的包名.类名获取对应.class文件的Class对象 Class Class.forName...