如何使用反射动态地通过名称调用 Java 中的方法?
Java 中的反射 API 允许您使用其字符串名称动态调用任何方法。使用 java.lang.reflect API 时,您可以按名称加载类,即使在编译时无法访问它们,这要归功于反射的强大机制。它使您能够使用反射动态调用任何方法,并使您能够从类中检索所有方法,包括私有方法和公共方法。
不熟悉 Java 的人可能会觉得这个想法很奇怪。由于在编译期间没有用于调用方法的显式代码,因此 Java 可以在运行时以字符串形式提供方法名称时执行该方法。反射是一种有效的机制,可让您灵活地执行不同的任务。
使用的方法
这里使用了两个函数 -
通过名称调用方法
通过名称在类中定位方法并调用它
方法 1:通过名称调用方法
getDeclaredMethod() 函数可用于通过名称调用方法。它具有以下语法。
语法
Class.getDeclaredMethod("方法名称", 参数类型)
此语法中的"方法名称"表示您正在查找的方法的名称。
方法的参数类型指定它将接受的参数类型。
该函数接受调用并返回一个包含方法地址的对象。稍后将使用此对象调用该方法。invoke 方法将用于调用该方法。该方法最初是使用通过invoke函数()从getDeclaredMethod获得的Method对象来调用的。
它的语法如下:
语法
methodObj.invoke(classObj, param1, param2...)
通过调用getDeclaredMethod()获取MethodObj使我们能够轻松地调用我们所需的选定方法。
参数param1、param2等显示应传递给方法的参数值。当方法没有参数时,您可以绕过null。
getDeclaredMethod()
该程序演示了如何使用Java中的Reflection API通过方法名称调用方法。它创建了"Tutorialspoint"类,其中包含打印消息的"printMessage"方法。在主方法中,它使用类对象获取"printMessage"的方法对象,并使用消息调用该方法。输出显示该方法已成功调用,并显示提供的消息。
算法
导入必要的 Java 包。
想出一个名为 Tutorialspoint 的类,其中包含一个接受 String 参数的 printMessage() 方法。
想出一个 main() 方法,该方法打印一条消息并创建一个 Tutorialspoint 对象。
获取 Tutorialspoint 类的 Class 对象。
获取 printMessage() 方法的 Method 对象。
在 Tutorialspoint 对象上调用 printMessage() 方法,并传入一个 String 参数。
捕获任何 InvocationTargetException 并打印原因(如果有)。
程序将打印指示成功的输出消息方法的调用。
示例
// 使用 Reflection API 通过方法名称调用方法的 Java 程序 import java.io.*; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Type; public class Tutorialspoint { public void printMessage(String message){ System.out.println("you called on me with the message:" + message); } public static void main(String[] args) throws Exception{ System.out.println("Java 使用 Reflection 允许您通过名称调用方法!"); // 创建类对象以获取其详细信息 Tutorialspoint obj = new Tutorialspoint(); Class<?> classObj = obj.getClass(); // 通过名称获取"printMessage"函数的方法对象 Method printMessage = classObj.getDeclaredMethod("printMessage", String.class); try { // 使用此类 obj 调用函数 // 传入类对象 printMessage.invoke(obj, "Welcome Students"); } catch (InvocationTargetException e){ System.out.println(e.getCause()); } } }
输出
Java uses Reflection to allow you to invoke a method by name! you called on me with the message:Welcome Students
方法 2:按名称在类中定位方法并调用它
如果我们不确定确切的方法参数,我们可以使用 getDeclaredMethods() API 来检索类的所有方法。此 API 返回一个 Method 对象数组,我们可以对其进行操作。
使用循环遍历这些 Method 小工具,并使用 getName() 方法按名称定位特定方法。您可以使用 getGenericParameterTypes() 方法和 getGenericReturnType() 方法获取有关方法参数的更多信息,以获取有关其返回类型的更多统计数据。一旦我们掌握了有关方法的参数和返回类型的重要统计数据,我们将使用调用方法之前提到的调用功能。
使用此方法,我们可以动态搜索路径并获取其信息,而无需事先知道其确切的参数。
语法
Method[] methods = Class.getDeclaredMethods()
numAdd()
该程序演示了如何使用 Java 中的 Reflection API 通过名称查找方法。它创建了一个类"Tutorialspoint",其中包含两个方法:"printMessage"和"numAdd"。在主方法中,它获取"Tutorialspoint"对象的类对象并使用 getDeclaredMethods() 检索所有声明的方法。然后,它遍历方法并检查方法名称是否为"numAdd"。如果匹配,则使用invoke()方法调用带有整数参数的方法。输出显示"numAdd"方法调用成功,并打印出所提供数字的总和。
算法
步骤 1 − 创建一个名为"Tutorialspoint"的类,其中包含两个方法:"printMessag"。它将接受一个字符串参数并打印一条消息,而"numAdd"接受两个整数参数并打印它们的总和。
步骤 3 - 在"numAdd"方法中,打印两个数字的总和。
步骤 4 - 在主方法中,打印一条消息,表明使用反射在 Java 中按名称查找方法。
步骤 4 - 创建"Tutorialspoint"类的对象。
步骤 5 - 借助 getClass() 方法获取所创建对象的类对象。
步骤 6 - 借助 getDeclaredMethods() 获取类中声明的所有方法。
步骤 7 - 使用for-each 循环。
步骤 8 - 检查方法名称是否等于"numAdd"。
步骤 9 - 如果匹配,则使用invoke()方法直接使用提供的参数调用该方法,传递对象和参数值。
步骤 10 - 如果在方法调用期间发生异常,则捕获InvocationTargetException。
步骤 11 - 程序将打印输出消息,指示方法调用成功以及提供的数字的总和。
示例
import java.io.*; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Type; public class Tutorialspoint { public void printMessage(String message){ System.out.println("you called on me with the message:" + message); } public void numAdd(int num1, int num2){ System.out.println("total is:" + (num1 + num2)); } public static void main(String[] args) throws Exception{ System.out.println("Using Java's Reflection, discover a method by name."); // 创建类对象以获取其详细信息 Tutorialspoint obj = new Tutorialspoint(); Class classObj = obj.getClass(); // 获取类中的所有方法 Method[] allMethods = classObj.getDeclaredMethods(); // 循环遍历方法以查找方法 numAdd() for (Method m : allMethods) { String methodName = m.getName(); if (methodName.equals("numAdd")) { try { // invoke the method directly with its // parameters m.invoke(obj, 20, 30); } catch (InvocationTargetException e) { } } } } }
输出
Using Java's Reflection, discover a method by name. total is:50
结论
反射可用于按名称动态调用方法。它对于调试、生成代码和扩展现有培训可能很有用。但是,谨慎使用反射非常重要,因为如果使用不当可能会有风险。