18.3.3 Java 8新增的方法参数反射

18.3.3 Java 8新增的方法参数反射

Java8java.lang.reflect包下新增了一个Executable抽象基类,Executable类对象代表可执行的类成员,该类派生了ConstructorMethod两个子类。

获取方法或构造器的形参个数 形参名

Executable基类提供了大量方法来获取修饰该方法构造器的注解信息;还提供了isVarArgs()方法用于判断该方法或构造器是否包含数量可变的形参,以及通过getModifiers()方法来获取该方法或构造器的修饰符。除此之外, Executable提供了如下两个方法来获取该方法或构造器的形参个数形参名

方法 描述
int getParameter() 获取该构造器或方法的形参个数
Parameter[] getParameters() 获取该构造器或方法的所有形参。

获取参数信息

上面第二个方法返回了一个Parameter数组, Parameter也是Java 8新增的APl,每个Parameter对象代表方法或构造器的一个参数。 Parameter也提供了大量方法来获取声明该参数的泛型信息,还提供了如下常用方法来获取参数信息。

方法 描述
getModifiers() 获取修饰该形参的修饰符。
String getName() 获取形参名
Type getParameterizedType() 获取带泛型的形参类型。
Cass<?> getType() 获取形参类型
boolean isNamePresent() 该方法返回该类的class件中是否包含了方法的形参名信息。
boolean isVarArgs() 该方法用于判断该参数是否为个数可变的形参。

需要指出的是,使用javac命令编译Java源文件时,默认生成的.class文件并不包含方法的形参名信息,因此调用isNamePresent()方法将会返回false,调用getName()方法也不能得到该参数的形参名。如果希望javac命令编译Java源文件时可以保留形参信息,则需要为该命令指定-parameters选项。

程序示例

如下程序示范了Java 8的方法参数反射功能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import java.lang.reflect.*;
import java.util.*;

class Test
{
public void replace(String str, List<String> list){}
}
public class MethodParameterTest
{
public static void main(String[] args)throws Exception
{
// 获取String的类
Class<Test> clazz = Test.class;
// 获取String类的带两个参数的replace()方法
Method replace = clazz.getMethod("replace"
, String.class, List.class);
// 获取指定方法的参数个数
System.out.println("replace方法参数个数:" + replace.getParameterCount());
// 获取replace的所有参数信息
Parameter[] parameters = replace.getParameters();
int index = 1;
// 遍历所有参数
for (Parameter p : parameters)
{
if (p.isNamePresent())
{
System.out.println("---第" + index++ + "个参数信息---");
System.out.println("参数名:" + p.getName());
System.out.println("形参类型:" + p.getType());
System.out.println("泛型类型:" + p.getParameterizedType());
}
}
}
}

上面程序先定义了一个包含简单的Test类,该类中包含一个replace(String str,List<String> list)方法,程序中先是获取了该方法,然后分别用于获取该方法的形参名,形参类型和泛型信息。
只有当该类的.class文件中包含形参名信息时,程序才会执行条件体内的三行粗体字代码。因此需要使用如下命令来编译该程序:
javac -parameters MethodParameterTest.java
上面命令中-parameters选项用于控制javac命令保留方法形参名信息。
运行该程序,即可看到如下输出:

1
2
3
4
5
6
7
8
9
10
11
12
G:\Desktop\随书源码\疯狂Java讲义第三版光盘\codes\18\18.3>javac -parameters MethodParameterTest.java

G:\Desktop\随书源码\疯狂Java讲义第三版光盘\codes\18\18.3>java MethodParameterTest
replace方法参数个数:2
---第1个参数信息---
参数名:str
形参类型:class java.lang.String
泛型类型:class java.lang.String
---第2个参数信息---
参数名:list
形参类型:interface java.util.List
泛型类型:java.util.List<java.lang.String>

本文重点

Java 8新增了方法参数反射功能,可以获取方法的参数的信息,如获取:

  • 形参的修饰符
  • 形参名
  • 形参个数等信息

要想保留形参名信息到.class文件中,则在编译时要在javac命令后面加上-parameters选项.