如何在 Java 中使用反射动态调用方法?
Java 中的反射 API 允许您使用其字符串名称动态调用任何方法。使用 java.lang.reflect API 时,即使在编译时无法访问类,您也可以通过名称加载类,这要归功于反射强大的机制。它使您能够使用反射动态调用任何方法,并使您可以检索类中的所有方法,包括私有方法和公共方法。
不熟悉 Java 的人可能会觉得这个想法很奇怪。在编译期间没有调用方法的显式代码,Java 可以在运行时提供方法名称作为字符串时执行该方法。反射是一种有效的机制,使您能够灵活地执行不同的任务。
使用的方法
这里使用了两个函数 -
按名称调用方法
在类中按名称定位方法并调用它
方法 1:使用其名称调用方法
可以使用 getDeclaredMethod() 函数按名称调用方法。它具有以下语法。
语法
Class.getDeclaredMethod("method name", parameterType)
此语法中的“方法名称”表示您要查找的方法的名称。
方法的 parameterType 指定它将接受的参数类型。
该函数接受一个调用并返回一个包含方法地址的对象。稍后将使用此对象调用该方法。invoke 方法将用于调用该方法。最初使用从 getDeclaredMethod 获得的 Method 对象通过使用 invoke 函数 () 调用该方法。
它具有以下语法 -
语法
methodObj.invoke(classObj, param1, param2...)
从调用 getDeclaredMethod() 获取 MethodObj 使我们能够轻松地调用我们想要选择的特定方法。
参数 param1、param2 等显示应传递给方法的参数值。当方法没有参数时,您可以绕过 null。
getDeclaredMethod()
该程序演示了如何使用 Java 中的反射 API 按名称调用方法。它创建了一个名为“Tutorialspoint”的类,其中包含一个打印消息的“printMessage”方法。在主方法中,它使用类对象获取“printMessage”的方法对象并使用消息调用它。输出显示了使用提供的消息成功调用该方法。
算法
导入必要的 Java 包。
创建一个名为 Tutorialspoint 的类,其中包含一个带 String 参数的 printMessage() 方法。
创建一个打印消息并创建 Tutorialspoint 对象的 main() 方法。
获取 Tutorialspoint 类的 Class 对象。
获取 printMessage() 方法的 Method 对象。
在 Tutorialspoint 对象上调用 printMessage() 方法,传入一个 String 参数。
捕获任何 InvocationTargetException 并打印任何原因。
程序将打印输出消息,指示方法已成功调用。
示例
// Java program for invoking method with its name with Reflection API
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 uses Reflection to allow you to invoke a method by name!");
// create class object to get its details
Tutorialspoint obj = new Tutorialspoint();
Class<?> classObj = obj.getClass();
// get method object for "printMessage" function by
// name
Method printMessage = classObj.getDeclaredMethod("printMessage", String.class);
try {
// invoke the function using this class obj
// pass in the class object
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() 方法获取有关其返回类型的更多信息。一旦我们获得了有关方法的参数和返回类型的必要信息,我们就可以使用之前提到的 invoke 函数来调用该方法。
使用此方法,我们可以动态搜索路径并获取其信息,而无需事先知道其确切参数。
语法
Method[] methods = Class.getDeclaredMethods()
numAdd()
该程序演示了如何使用 Java 中的反射 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.");
// create class object for obtaining its details
Tutorialspoint obj = new Tutorialspoint();
Class classObj = obj.getClass();
// get all methods in the class
Method[] allMethods = classObj.getDeclaredMethods();
// loop through the methods to look for the method 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
结论
反射可用于动态调用方法。它可能对调试、代码生成和扩展现有培训很有用。但是,务必谨慎使用反射,因为如果使用不当,它可能会很危险。
数据结构
网络
关系数据库管理系统
操作系统
Java
iOS
HTML
CSS
Android
Python
C 编程
C++
C#
MongoDB
MySQL
Javascript
PHP