本文已参与「新人创作礼」活动,一起开启掘金创作之路。
这篇文章我们来介绍一下如何通过反射来获取Class 中的方法,并学习如何调用这些方法。我们使用这篇文章中的类结构作为例子来介绍。
获取并调用类中的public 方法
首先我们来看一下如何获取并调用类中的public 方法。在示例类中的public 方法是doHomework、playGame。我们这里使用doHomework 来做介绍。
Class<?> clazz = Student.class;
try {
Method doHomework = clazz.getMethod("doHomework", String.class);
Student student = new Student("Jack", 23);
doHomework.invoke(student, "math");
}
catch (Exception e) {
e.printStackTrace();
}
我们来拆解一下上面这段代码。首先,我们需要通过clazz.getMethod 方法,获得这个“方法对象”。
在getMethod 方法中,第一个参数是要获取的方法名,之后的参数为待获取的方法的所有的参数类型。待获取的方法中有多少个参数,那么在第一个参数后面就会有多少个参数。
在我们得到了method 对象之后,我们就可以调用method 对象的invoke 方法去调用这个方法了。
在invoke 方法中,第一个参数是实例化的对象,第一个参数之后的参数和待调用的函数一致,输入的是待处理的参数。
获取并调用类中的private 方法
在示例类中,私有方法是cleanClassroom,我们来看一下如何获取并调用私有方法。
try {
Method cleanClassroom = clazz.getDeclaredMethod("cleanClassroom");
work.setAccessible(true);
Student student = new Student("Amy", 29);
work.invoke(studnet);
}
catch (Exception e) {
e.printStackTrace();
}
细心的读者可以很快地发现,在获取私有方法的时候,和获取私有属性的步骤十分类似。获取私有方法,需要调用getDeclaredMethod 方法,同时需要调用setAccessible(true) 来允许私有方法可以访问。
获取并调用类中的静态方法
在示例类中的静态方法为getMaxAge,对于这个方法,我们来看一下如何通过反射来操作它。
try {
Method getMaxAget = clazz.getDeclaredMethod("getMaxAget");
getMaxAget.setAccessible(true);
// 由于这个是静态方法,所以在调用它的时候,就不需要传入实例化对象,所以只传入一个null 即可。
Object value = getMaxAget.invoke(null);
System.out.println("the value from getMaxAge is: " + value);
} catch (Exception e) {
e.printStackTrace();
}
细心的读者也可以发现,在调用静态方法的时候,很像处理静态字段一下,在invoke 中的第一个参数只需要传入null 就行了。
获取并调用类中的所有方法
我们最后来看一下如何获取并调用类中的所有的方法。
Student student = new Student();
Method[] declaredMethods = clazz.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
Class<?>[] parameterTypes = declaredMethod.getParameterTypes();
try {
declaredMethod.setAccessible(true);
Object result;
if (parameterTypes.length == 0) {
result = declaredMethod.invoke(student);
} else {
result = declaredMethod.invoke(student, "hi!");
}
System.out.println("method name: " + declaredMethod.getName() + ", paramenter type: " + Arrays.toString(parameterTypes) + ", return value: " + result);
} catch (Exception e) {
e.printStackTrace();
}
}
对比与获取类中的所有字段,我们发现获取所有方法也很类似,方法签名也比较像。
我们只需要使用clazz.getDeclaredMethods(); 就可以获得到类中的所有方法了。
总结
这篇文章我们介绍的就是如何通过反射来获取类中的方法了。看似内容比较多,其实也是很有结构的。对于读者来说也是比较好阅读理解。希望读者可以加以运用,一定会带来很多方法之处。